我已经建立了一个 WCF 服务,它打算在 Kerberos 下运行。我遇到的问题是,每当我从服务向客户端抛出异常时,它似乎都会对异常详细信息发出单独的请求,并且由于“远程服务器不满足相互身份验证的要求”而失败。 ' .
好消息 - 不抛出异常的服务调用请求工作正常。
我目前的后备方案是允许 NTLM,我想删除它。我想了解问题的核心,试图克服“Kerberos 总是很困难”的心态。
基本网络细节:
- 根据 NetBios + FQDN 名称和应用程序池的服务帐户为服务注册 SPN。(回退到 http 机器 SPN 对我们不可用
- 匿名被禁用
尝试的异常类型:
- 重新抛出原始异常(客户端可以访问基本异常类型)
FaultException,(虽然我不需要自定义异常,它可能适用于)+ 将以下内容添加到每个 web 服务方法:
[FaultContract(typeof(FaultException))]
客户端细节
设置 ClientCredential:(客户端)
credentials.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;
credentials.Windows.AllowNtlm = false; // Set to true to allow it to work;
credentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Delegation;
以前问题的其他修复:
SpnEndpointIdentity设置,感谢这个问题
SpnEndpointIdentity spnEndpointIdentity = new SpnEndpointIdentity("");
var address = new EndpointAddress(EndpointName, spnEndpointIdentity)
要停止407 代理错误:
BasicHttpBinding.UseDefaultWebProxy = false;
客户端收到的异常:(缩写堆栈跟踪)
(它似乎表明ProcessGetResponseWebException调用正在尝试检索异常详细信息)
System.ServiceModel.CommunicationException was unhandled
Message=An error (The request was canceled) occurred while transmitting data over the HTTP channel.
StackTrace:
at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Project.IMetadataManagement.GetMetadata(String identifier)
InnerException: System.Net.WebException
InnerException: System.Net.ProtocolViolationException
Message=The requirement for mutual authentication was not met by the remote server.
服务器端细节
在网络配置中:
includeExceptionDetailInFaults为真
<behavior name="Project.MetadataBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
绑定:
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpointBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
Windows 身份验证设置
<system.webServer>
<security>
<authentication>
<windowsAuthentication enabled="true" useKernelMode="true" useAppPoolCredentials="true" >
<providers>
<clear />
<add value="Negotiate" />
<add value="NTLM" />
</providers>
<extendedProtection tokenChecking="None" />
</windowsAuthentication>
<anonymousAuthentication enabled="false" />
</authentication>
</security>
</system.webServer>
服务示例
<services>
<service behaviorConfiguration="Project.MetadataBehavior" name="Project.MetadataManagement">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpEndpointBinding" contract="Project.IMetadataManagement">
</endpoint>
</service>
任何和所有的帮助表示赞赏。我已经忽略了实际的项目名称空间,所以希望我没有留下任何笨拙的错位。
谢谢。