【问题标题】:WCF configuration using kerberos fails on certain domains使用 kerberos 的 WCF 配置在某些域上失败
【发布时间】:2016-07-13 16:54:02
【问题描述】:

我不太确定,这个问题就在 stackoverflow 上……也许它属于 serverfault……总之,这里是:

我们有实现 WCF 服务的服务器/客户端设置。客户端和服务都在域用户下运行。托管服务器端服务的域用户也是服务器上的本地管理员。此设置适用于大多数客户。某些客户抱怨说,他们无法使用服务器主机名使用单点登录 (SSO)。我们跟进该问题并发现,如果我们指定服务器的 IP 地址,一切正常。对我来说,这表明我们的配置工作正常,但某些域配置会干扰我们的设置。

WCF 配置:

<configuration>
  <system.serviceModel>
    <client>
      <!-- minimal needed config, address will be ignored -->
      <endpoint address="net.tcp://inihost:10100/ApplicationService" binding="netTcpBinding"
                bindingConfiguration="nosecNetTcpBinding" name="ApplicationServiceHost"
                    contract="Kaba.Exos.Transport.Infrastructure.ICommandExecutionService" />
      <endpoint address="net.tcp://inihost:10100/ApplicationServiceSSO"     binding="netTcpBinding"
                bindingConfiguration="ssoNetTcpBinding"     name="ApplicationServiceSsoHost"
                    contract="Kaba.Exos.Transport.Infrastructure.ICommandExecutionService" />
    </client>
    <bindings>
      <netTcpBinding>
        <binding name="nosecNetTcpBinding" receiveTimeout="00:30:00"     sendTimeout="00:30:00" maxBufferPoolSize="134217728" maxBufferSize="134217728"     maxReceivedMessageSize="134217728">
          <security mode="None"></security>
        </binding>
        <binding name="ssoNetTcpBinding" receiveTimeout="00:30:00"     sendTimeout="00:30:00" maxBufferPoolSize="134217728" maxBufferSize="134217728"     maxReceivedMessageSize="134217728">
          <security mode="Transport">
            <message clientCredentialType="Windows" />
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
  </system.serviceModel>
</configuration>

设置 WCF 连接的 C# 代码:

        var exeConfigFileFullPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\" + exeConfigFilename;

        var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = exeConfigFileFullPath };

        var newConfig = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

        try
        {
            this.channelFactory = new ConfigurationChannelFactory<ICommandExecutionServiceChannel>(endpointConfigurationName, newConfig, null);
        }
        catch (Exception e)
        {
            traceLogger.TraceException(e, "CommandExecutionServiceClient", "CommandExecutionServiceClient");
            throw;
        }

        if (!string.IsNullOrEmpty(serviceConnection.Item1))
        {
            var builder = new UriBuilder(this.channelFactory.Endpoint.Address.Uri) { Host = serviceConnection.Item1, Port = serviceConnection.Item2 };
            this.channelFactory.Endpoint.Address = new EndpointAddress(builder.Uri);
        }

        this.AddForwardExceptionToClientEndpointBehavior();
    }

在实施了两个小改动之后......

在 WCF 文件中

  <!-- minimal needed config, address will be ignored -->
  <endpoint address="net.tcp://inihost:10100/ApplicationServiceSSO" binding="netTcpBinding"
            bindingConfiguration="ssoNetTcpBinding" name="ApplicationServiceSsoHost"
            contract="Kaba.Exos.Transport.Infrastructure.ICommandExecutionService" behaviorConfiguration="kerberosFallbackToNtlm">

    <behaviors>
      <endpointBehaviors>
        <behavior name="kerberosFallbackToNtlm">
          <clientCredentials>
            <!-- if Kerberos is required, set the following value to false and configure the proper identity for Exos9300ServiceSsoHost above. -->
            <windows allowNtlm="true" />
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>

在代码中

this.channelFactory.Endpoint.Address = new EndpointAddress(builder.Uri, EndpointIdentity.CreateSpnIdentity(String.Empty));

此设置适用于域设置,我们之前遇到“无法建立 SSPI 上下文”错误。

现在我的问题:

为什么这个设置在一个域上工作得很好,但在另一个域上却失败了。是否有任何可能影响此行为的 Active Directory 设置?

【问题讨论】:

    标签: c# active-directory wcf-security


    【解决方案1】:

    原来我被误导了......因此,如果服务由本地管理员用户托管,则服务身份验证将回退到 NTLM。

    我确实设法通过删除默认创建的 SPN 并手动添加新的 SPN 来使此方案正常工作。

    要删除默认创建的现有 SPN:

    setspn -D HOST/{HOSTNAME server} {HOSTNAME server}
    

    为域用户添加新的 SPN:

    setspn -S HOST/{HOSTNAME server} {Domainuser service}
    

    注意!!

    一旦我发出命令:

    setspn -D HOST/{FQDN server} {HOSTNAME server}
    

    并设法禁止我的服务器使用域控制器对任何域用户进行身份验证,因为它不再在信任数据库中。

    【讨论】:

      猜你喜欢
      • 2010-11-06
      • 2015-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多