WCF和Kerberos身份验证
我遵循了许多msdn文章和codeplex指导,但无法让WCF与Kerberos身份验证和委派一起工作,并希望得到一些帮助。WCF和Kerberos身份验证
设置
我有一个IIS网站的WCF服务的远程机
- 在IIS 6.0在Windows 2003 R2 - SP 2
- 的SPN机已添加(http/myserver & & http/myserver:8080)
- 为IIS应用程序池创建了一个AD帐户
- 广告帐户的设置,允许委派(使用Kerberos),设置为true
我使用8080 Brian Booth's debug site和站点通行证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'“
事件日志
下面的错误是在事件日志中:
例外: 系统.ServiceModel.ServiceActivationException: 由于 compila中的异常,服务“/Service.svc”不能为 激活灰。 的例外消息是:此服务的安全设置 需要“匿名”身份验证,但 未启用托管此服务的IIS 应用程序。
我不明白。此服务的重点是不允许匿名身份验证,每个用户/请求必须使用Kerberos票据进行身份验证,然后将其传递到其他计算机。
我应该如何配置此WCF服务以进行Kerberos身份验证和委派?
修订1
读取this SO question后我删除元数据端点。这并没有解决这个问题。
修订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请求是未经授权的客户端 认证方案 '协商'。从服务器接收认证头 是 “协商SOMEHUGESCARYKEYHERE
东西我注意到:在客户端和服务器的配置似乎并没有在安全模式达成一致。
在原始部分中,您在web.config中有<security>.....
(省略了mode =“message”),并且在客户端有<security mode="Message">
。
编辑完成后,似乎客户端不变,但服务器(web.config)现在包含<security mode="TransportCredentialOnly">
。
问题的确是:你能保证在客户端和被调用的服务器之间只有一个网络分支吗?即这是企业防火墙的后面吗?在这种情况下,我会推荐netTcp绑定两端的<security mode="Transport">
。
如果情况并非如此,那么wsHttpBinding(支持更多安全性和可靠性功能,但速度更慢,更“重”)或basicHttpBinding可以。在这种情况下,您必须在两端使用<security mode="Message">
,并使用证书对服务进行身份验证(以便服务和客户端具有用于加密的公共“秘密”)。
我会尝试在开始时忽略模拟部分,并首先获取服务和客户端之间的基本通信和相互身份验证,并首先运行 - 一旦到位,您可以开始向其添加模拟位,并且您可以始终使用已知的配置工作。
David Sackstein有一个great series of blog posts解释行业大师Juval Lowy已经确定的五个安全情景(在他的Programming WCF书--WCF圣经中)是最常见也是最有用的 - 为了限制可能的参数组合数量你可能想调整。其中之一是一个“互联网”的情况,如果你的服务是面向外部的话,这种情况可能适用于此。
马克
对我来说,当前的设置没有问题:
在服务器上:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBindingConf" useDefaultWebProxy="true"/>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="returnFaults" name="Epze.BusinessLayer.ZeitManager">
<endpoint binding="wsHttpBinding" bindingConfiguration="wsHttpBindingConf" contract="Epze.Contract.IZeitManager"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="returnFaults">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceAuthorization impersonateCallerForAllOperations="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
设置上的WCF所有方法如下属性:
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
在客户端:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IZeitManager" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm=""/>
<message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" establishSecurityContext="true"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="Delegation">
<clientCredentials>
<windows allowedImpersonationLevel="Delegation" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="http://server.mydomain.net/ePZEsvc/ZeitManager.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IZeitManager"
contract="External.Epze.IZeitManager" name="WSHttpBinding_IZeitManager" behaviorConfiguration="Delegation">
<identity>
<servicePrincipalName value="HOST/localhost"/>
</identity>
</endpoint>
</client>
</system.serviceModel>
HTH,斯文
身份验证方法的IIS设置如何?匿名访问是否关闭? – Jonathan 2011-06-10 09:38:08
我启用了Windows身份验证和匿名访问。但是,在为您的服务添加mex(IMetadataExchange)端点时,您只需要匿名。 – 2011-06-14 14:11:03
你应该试试你的初始配置,并确保设置IIS是在同一time.The原因匿名和Windows身份验证时,您正在使用的wsHttpBinding默认的安全是信息安全除非您想要执行https,否则没有定义传输安全性。 SO Clr声明它需要在IIS上启用匿名身份验证。
您需要在客户端配置中指定一个behaviorConfiguration。 SVCUtil不会自动生成。这解决了我的问题,我现在成功地使用了Kerberos。尽管这是一个使命!
<client>
<endpoint address="..."
binding="customBinding" bindingConfiguration="..."
contract="..." name="..." behaviorConfiguration="ImpersonationBehavior" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="ImpersonationBehavior">
<clientCredentials>
<windows allowedImpersonationLevel="Impersonation"/> </clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
请注意,我发布和删除了类似的东西昨天,这篇文章包括基于更多的研究修订,应该更清晰的阅读。 – blu 2009-08-18 18:02:22
我根据marc_s的反馈添加了修改后的应用配置。 – blu 2009-08-18 21:06:44