通过消息头的 WCF 安全性

Posted

技术标签:

【中文标题】通过消息头的 WCF 安全性【英文标题】:WCF security via message headers 【发布时间】:2011-02-05 07:02:30 【问题描述】:

我正在尝试为某些 WCF 服务实现“某种”服务器-客户端和零配置安全性。

我在 www 上找到的最好(对我来说也是最简单的)解决方案是http://www.dotnetjack.com/post/Automate-passing-valuable-information-in-WCF-headers.aspx(客户端)和http://www.dotnetjack.com/post/Processing-custom-WCF-header-values-at-server-side.aspx(对应的服务器端)中描述的解决方案。

下面是我对 RequestAuth 的实现(在上面的第一个链接中描述):

using System;
using System.Diagnostics;
using System.ServiceModel;
using System.ServiceModel.Configuration;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;

namespace AuthLibrary

    /// <summary>
    /// Ref: http://www.dotnetjack.com/post/Automate-passing-valuable-information-in-WCF-headers.aspx
    /// </summary>
    public class RequestAuth : BehaviorExtensionElement, IClientMessageInspector, IEndpointBehavior
    
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private string headerName = "AuthKey";

        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private string headerNamespace = "http://some.url";

        public override Type BehaviorType
        
            get  return typeof(RequestAuth); 
        

        protected override object CreateBehavior()
        
            return new RequestAuth();
        

        #region IClientMessageInspector Members

        // Keeping in mind that I am SENDING something to the server,
        // I only need to implement the BeforeSendRequest method

        public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
        
            throw new NotImplementedException();
        

        public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
        
            MessageHeader<string> header = new MessageHeader<string>();
            header.Actor = "Anyone";
            header.Content = "TopSecretKey";

            //Creating an untyped header to add to the WCF context 
            MessageHeader unTypedHeader = header.GetUntypedHeader(headerName, headerNamespace);

            //Add the header to the current request 
            request.Headers.Add(unTypedHeader);

            return null;
        

        #endregion

        #region IEndpointBehavior Members

        public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        
            throw new NotImplementedException();
        

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        
            clientRuntime.MessageInspectors.Add(this);
        

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        
            throw new NotImplementedException();
        

        public void Validate(ServiceEndpoint endpoint)
        
            throw new NotImplementedException();
        

        #endregion
    

所以首先我把这段代码放在我的客户端 WinForms 应用程序中,但后来我在签署它时遇到了问题,因为我还必须签署所有第三方引用,尽管 http://msdn.microsoft.com/en-us/library/h4fa028b(v=VS.80).aspx 在“什么不应该被强命名”部分声明:

一般来说,您应该避免使用强命名的应用程序 EXE 程序集。强命名的应用程序或组件不能引用弱命名的组件,因此强命名 EXE 会阻止 EXE 引用与应用程序一起部署的弱命名 DLL。

因此,Visual Studio 项目系统不使用强名称应用程序 EXE。相反,它对应用程序清单进行强命名,该清单在内部指向弱命名的应用程序 EXE。

我希望 VS 能够避免这个问题,但我没有运气,它抱怨所有未签名的引用,所以我在我的解决方案中创建了一个单独的“WCF 服务库”项目,其中只包含上面的代码并签署了那个。

此时整个解决方案编译好了。

这是我的问题:

当我启动“WCF 服务配置编辑器”时,我能够添加新的行为元素扩展(比如“AuthExtension”),但是当我尝试将该扩展添加到我的端点行为时,它给了我:

调用的目标已抛出异常。

所以我被困在这里了。

有什么想法吗?

【问题讨论】:

【参考方案1】:

你有一些:

        throw new NotImplementedException(); 

在您的代码中。这些可能是被抛出的异常。尝试删除这些,看看是否会出现相同的错误。

【讨论】:

我真的不认为这是问题所在,我没有故意实现那些方法,只是因为我没有使用它们。【参考方案2】:

Shiraz Bhaiji 是对的。该框架确实调用了那些您抛出未实现异常的方法。删除它。

【讨论】:

非常抱歉,我已经在 WCF 安全问题上改变了方向,因此无法验证。记录在案:毕竟我已经尝试过了,codeproject.com/KB/WCF/wcfcertificates.aspx 为我成功了。

以上是关于通过消息头的 WCF 安全性的主要内容,如果未能解决你的问题,请参考以下文章

kafkakafka 消息头的强大功能

tomcat9以后对,请求消息头的严格字符要求

WCF自定义错误处理(IErrorHandler接口的用法)

读取 SOAP 消息头 WCF

如何在双工回调中读取 WCF 消息头?

WCF 错误 - 安全处理器无法在消息中找到安全标头