2

我已经建立了一个 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>

任何和所有的帮助表示赞赏。我已经忽略了实际的项目名称空间,所以希望我没有留下任何笨拙的错位。

谢谢。

4

0 回答 0