我关注了许多 msdn 文章和 codeplex 指南,但无法让 WCF 与 Kerberos 身份验证和委派一起使用,希望能得到一些帮助。
设置
我在远程机器上的 IIS 网站中有 WCF 服务
- Windows 2003 R2 上的 IIS 6.0 - SP 2
- 已添加机器的 SPN (http/myserver && http/myserver:8080)
- 已为 IIS 应用程序池创建 AD 帐户
- AD 帐户具有设置,允许委派(对于 Kerberos),设置为 true
我在 8080 上使用Brian Booth 的调试站点,该站点通过了 Kerberos 委派的所有要求。调试 IIS 站点关闭了匿名身份验证,并打开了集成 Windows 身份验证。
我已将这些设置镜像到托管 WCF 服务的站点。
网络服务 - 网络配置(原始)
<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>
网络服务 - 网络方法
[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 票证进行身份验证,然后将它们传递给其他机器。
我应该如何为 Kerberos 身份验证和委派配置此 WCF 服务?
修订版 1
在阅读了这个 SO question之后,我删除了元数据端点。这并没有解决问题。
修订版 2
经过更多研究,我发现一些帖子建议将 wsHttpBinding 更改为 basicHttpBinding。对 web.config 的该部分的修改已包含在下面,并且服务端点已更新为引用该绑定。
Web 服务 - Web Config(修订版)
<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 请求未经客户端身份验证方案“协商”的授权。从服务器收到的身份验证标头是 'Negotiate SOMEHUGESARYKEYHERE