WCF 和 Kerberos 身份验证
我遵循了大量的 msdn 文章和 codeplex 指南,但无法让 WCF 与 Kerberos 身份验证和委派一起使用,并且希望得到一些帮助。
安装
我在远程计算机上的 IIS 网站中拥有 WCF 服务
- Windows 2003 R2 - SP 2 上的 IIS 6.0
- 已添加该计算机的 SPN (http/myserver && http/myserver: 8080)
- 已为 IIS 应用程序池创建 AD 帐户
- AD 帐户具有设置,允许委派(对于 Kerberos),设置为 true
我正在使用 Brian Booth 在 8080 上的调试站点 并且该站点通过了 Kerberos 委派的所有要求。调试 IIS 站点已关闭匿名身份验证,并打开集成 Windows 身份验证。
我已将这些设置镜像到托管 WCF 服务的站点。
Web 服务 - Web 配置(原始)
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WsHttpBindingConfig">
<security>
<message negotiateServiceCredential="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="ServiceBehavior" name="Service">
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="WsHttpBindingConfig"
contract="IService">
<identity>
<servicePrincipalName value="http/myserver" />
<dns value="" />
</identity>
</endpoint>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceAuthorization
impersonateCallerForAllOperations="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Web 服务 - Web 方法
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public string GetCurrentUserName()
{
string name = WindowsIdentity.GetCurrent().Name;
return name;
}
客户端应用程序 - 应用程序配置
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService"
... />
...
<security mode="Message">
<transport clientCredentialType="Windows"
proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows"
negotiateServiceCredential="true"
algorithmSuite="Default"
establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://myserver/Service.svc"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService"
contract="KerberosService.IService"
name="WSHttpBinding_IService">
<identity>
<servicePrincipalName value="http/myserver" />
</identity>
</endpoint>
</client>
</system.serviceModel>
应用程序错误
以下内容当我的测试应用程序(WinForms 应用程序)尝试调用 Web 方法时发生错误:
“HTTP 请求未经授权 客户端认证方案 '匿名的'。身份验证标头 从服务器收到的是 ‘谈判,NTLM’。”
事件日志
事件日志中存在以下错误:
异常: System.ServiceModel.ServiceActivationException: 服务“/Service.svc”不能 由于期间异常而激活 汇编。异常消息 是:此服务的安全设置 需要“匿名”身份验证,但是 没有为 IIS 启用它 托管此服务的应用程序。
我不明白。该服务的重点是不允许匿名身份验证,每个用户/请求都必须使用 Kerberos 票证进行身份验证,然后将它们传递到其他计算机。
我应该如何配置此 WCF 服务以进行 Kerberos 身份验证和委派?
修订版 1
阅读这个问题后我删除了元数据端点。这并没有解决问题。
修订版 2
经过更多研究,我发现一些帖子建议将 wsHttpBinding 更改为 basicHttpBinding。下面包含了对 web.config 的该部分的修改,并且服务端点已更新为引用该绑定。
Web 服务 - Web 配置(修订版)
<basicHttpBinding>
<binding name="basicBindingConfig">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"
proxyCredentialType="Windows"
realm="" />
</security>
</binding>
</basicHttpBinding>
客户端应用程序 - 应用程序配置(修订版)
<!-- ... -->
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"
proxyCredentialType="Windows"
realm="" />
<message clientCredentialType="UserName"
algorithmSuite="Default" />
</security>
<!-- ... -->
错误(修订版)
当前错误看起来包含 Kerberos身份验证标头。
HTTP 请求未经授权 客户端认证方案 '谈判'。身份验证标头 从服务器收到的是 '在这里协商一些巨大的钥匙
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
对我来说,当前设置确实有效:
在服务器上:
在 WCF 的所有方法上设置以下属性:
在客户端上:
HTH、Sven
For me the current setup does work:
On the Server:
Set the following attribute on all methods for the WCF:
On the Client:
HTH, Sven
我注意到的一件事:客户端和服务器配置似乎在安全模式上不一致。
在原始部分中,web.config 中有
.....
(省略了 mode="message"),并且
在客户端。编辑后,客户端似乎没有更改,但服务器 (web.config) 现在包含
。真正的问题是:您能否保证客户端和被调用的服务器之间只有一条网络线路?即,这是在公司防火墙后面吗?在这种情况下,我建议在两端使用
绑定 netTcp。如果情况并非如此,那么您可以使用 wsHttpBinding (它支持更多安全性和可靠性功能,但速度较慢且“较重”)或 basicHttpBinding。在这种情况下,您必须在两端使用
,并使用证书对服务进行身份验证(以便服务和客户端拥有共同的“秘密”)用于加密)。我会尝试从一开始就忽略模拟部分,而只是首先启动并运行服务和客户端之间的基本通信和相互身份验证 - 一旦到位,您就可以开始向其中添加模拟位,并且您始终可以依靠可行的已知配置。
大卫·萨克斯坦有一个 一系列精彩的博客文章解释了行业大师 Juval Lowy 确定的五种安全场景(在他的 Programming WCF 书 - WCF 圣经)是最常见和最有用的 - 为了限制您可能想要调整的参数的可能组合的数量。其中之一是“互联网”场景,如果您的服务是面向外部的,则可能适用于此。
马克
Something that I notice: the client and server config don't seem to agree on security mode.
In the original section, you have
<security>.....
in the web.config (omitted the mode="message"), and<security mode="Message">
on the client side.After your edit, it seems that the client side is unchanged, but the server (web.config) now contains
<security mode="TransportCredentialOnly">
.The question really is: can you guarantee that there's only ever going to be one network leg between the client and the server being called? I.e. is this behind a corporate firewall? In that case, I would recommend netTcp binding with
<security mode="Transport">
on both ends.If that's not the case, then you're ok with either wsHttpBinding (which supports more security and reliability features, but is slower and "heavier") or basicHttpBinding. In that case, you would have to use
<security mode="Message">
on both ends, and authenticate the service with a certificate (so that the service and client have a common "secret" which to use for encryption).I would try to leave out the impersonation parts out for the beginning and just get the basic communication and mutual authentication between service and client up and running first - once that's in place, you can start adding the impersonation bits to it, and you can always fall back on a known configuration which works.
David Sackstein has a great series of blog posts explaining the five security scenarios that industry guru Juval Lowy has identified (in his Programming WCF book - the WCF Bible) as the most common and most useful - in order to limit the number of possible combinations of parameters you might want to tweak. One of them is a "Internet" scenario which would probably apply here, if your service is outward facing.
Marc
您需要在客户端配置中指定behaviorConfiguration。 SVCUtil 不会自动生成。这解决了我的问题,我现在可以成功使用 Kerberos。但这是一个使命!
You need to specify a behaviorConfiguration in your client config. SVCUtil does not auto generate. This resolved my issue and I am now successfully using Kerberos. It was a mission though!
您应该尝试初始配置,并确保同时将 IIS 设置为匿名和 Windows 身份验证。原因是当您使用 wsHttpBinding 时,默认安全性是消息安全性,并且没有定义传输安全性,除非您想要执行 https 。 SO Clr 声明它需要在 IIS 上打开匿名身份验证。
You should try your initial configuration and make sure to set the IIS to be anonymous and windows authentication at the same time.The reason is when you are using wsHttpBinding default security is message security and there is no transport security defined unless you want to do https. SO Clr states that it needs anonymous authentication turned-on on the IIS.