如何使用共享密钥限制对 WCF 服务的访问

Posted

技术标签:

【中文标题】如何使用共享密钥限制对 WCF 服务的访问【英文标题】:How to restrict access to a WCF service with a shared key 【发布时间】:2010-11-28 09:52:01 【问题描述】:

我有一些服务正在被安全区域内的客户端使用。我被要求保护这些服务,防止开发客户错误地连接到错误的服务。

这个想法是在客户端和服务主机的配置中设置的预共享密钥(如 guid)。每当客户端尝试使用服务时,它必须提供正确的密钥。

我将如何配置服务来实现这种安全性?需要多少定制?

【问题讨论】:

【参考方案1】:

您可以轻松地为每个调用添加自定义消息头 - 实际上很容易做到,而且它不会“污染”您的实际服务合同,例如您不必为了传递它而在服务调用中添加额外的参数。

有关如何实现此目的的信息,请参阅这些文章:

WCF Custom Message Headers HOw do I add a custom header to every WCF message? WCF Messaging fundamentals

基本上,您需要将对服务的调用包装在 OperationContext 中 - 仅此而已,不需要 ClientMessageInspector 和其他技巧 :-)

 using (OperationContextScope scope = new OperationContextScope(proxy))
 
     Guid myToken = Guid.NewGuid();

     MessageHeader<Guid> mhg = new MessageHeader<Guid>(myToken);
     MessageHeader untyped = mhg.GetUntypedHeader("token", "ns");

     OperationContext.Current.OutgoingMessageHeaders.Add(untyped);

     proxy.DoOperation(...);
  

在服务器端,您可以简单地检查IncomingMessageHeaders 集合:

Guid myToken = OperationContext.Current.
                 IncomingMessageHeaders.GetHeader<Guid>("token", "ns");

马克

【讨论】:

嗨,marc,假设 Columbo 没有为服务配置其他安全性,此解决方案是否仍会导致 WCF 消息内容被加密? @Xiaofu:默认情况下(除非您明确将其关闭),所有 WCF 消息都经过加密和数字签名。【参考方案2】:

我会让客户端将密钥作为额外的消息标头发送,并创建一个 IDispatchMessageInspector 来检查标头并选择性地拒绝它。 This代码项目文章描述了基于IP地址的过滤部分。

【讨论】:

谢谢,我喜欢这种方法的外观。我已经围绕这个想法进行了一些搜索,看起来我应该使用 IClientMessageInspector 在客户端插入密钥 - 实现为端点行为。然后在服务器端,我将有一个实现 IDispatchMessageInspector 检查密钥的行为。最后一件事 - wcf 中是否有任何现成的东西可以实现类似的目标,但不需要自定义行为? 如果您不使用 WCF 安全功能,您可以将它们用于此方法。在这种情况下,我将为每个客户端应用程序创建一个证书,并在每个服务中检查允许的客户端证书。我想你可以对用户名/密码做同样的事情,尽管这也会迫使你使用 HTTPS。 谢谢,我们之前考虑过用户/通行证身份验证,但我们在 ssl 和网络配置方面遇到了一些问题,这意味着我们开始寻找其他方法来满足要求。根据我今天所学到的,我想我会使用这种在标头中发送共享密钥的方法。所以现在只是做一个小测试项目:)【参考方案3】:

如果您使用密钥执行此操作,您将更改服务合同以包含将放置密钥的字段。然后在服务器端检查密钥中的值。

但是,在您的情况下,您可以通过网络配置限制允许哪些 IP 地址访问服务。这比更改服务的签名要少。

【讨论】:

这不是一个好主意——那样的话,你必须改变你的合同,并且你用基础设施/指导字段“污染”你的实际业务逻辑。我不会推荐这种方法。

以上是关于如何使用共享密钥限制对 WCF 服务的访问的主要内容,如果未能解决你的问题,请参考以下文章

如何限制对共享对象中符号的访问?

使用GCP API密钥限制对特定GCP App Engine服务的访问?

如何对 WCF 服务进行单元测试?

如何限制对 FTP 文件夹的访问?

如何限制 WCF 服务的请求执行时间?

如何使用 svcutil 从使用限制隐藏元素的 Web 服务生成 C# WCF 代理?