通过消息头的 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 安全性的主要内容,如果未能解决你的问题,请参考以下文章