WCF:无法满足安全令牌请求,因为身份验证失败

时间:2009-10-28 18:06:45

标签: c# wcf .net-3.5 wshttpbinding channelfactory

我在同一台机器上有两个WCF服务。一个是出版商,一个是听众。

发布者基于和端点动态创建代理。我在这样的代码中配置代理:

            WSHttpBinding binding = new WSHttpBinding(SecurityMode.Message, true);
            binding.Security.Message.NegotiateServiceCredential = true;
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
            binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
            binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
            binding.Security.Message.EstablishSecurityContext = true;
            binding.ReliableSession.Enabled = true;
            binding.TransactionFlow = true;
            return binding;

然后......

            Binding binding = GetBindingFromAddress(address);

            ChannelFactory<T> factory = new ChannelFactory<T>(binding);
            factory.Credentials.UserName.UserName = "an account on the machine";
            factory.Credentials.UserName.Password = "a password for that account";

            T proxy = factory.CreateChannel(new EndpointAddress(address));

当我去打电话时,我收到上述错误。这是我的监听器配置文件:

   <service behaviorConfiguration="MEX Enabled" name="InvoiceSubscriber">
<endpoint binding="wsHttpBinding"
          bindingConfiguration="ReliableTransactionalHTTP"
          contract="AtlanticBT.SubscriptionService.Contracts.v1.IAtlanticEvents">
 <identity>
  <dns value="localhost" />
 </identity>
</endpoint>

        <bindings>
        <wsHttpBinding>
            <binding name="ReliableTransactionalHTTP" transactionFlow="true">
                <reliableSession enabled="true"/>
      <security mode="Message">
        <transport clientCredentialType="Windows" proxyCredentialType="None" realm=""/>
        <message clientCredentialType="Windows" negotiateServiceCredential="true" 
                 algorithmSuite="Default" establishSecurityContext="true"/>
      </security>
            </binding>
  </wsHttpBinding>
    </bindings>

我已经检查了托管服务的目录上的所有ACL,看起来它们是正确的。 IIS安全性设置为匿名访问和Windows身份验证。

因此,如果我在代码中明确设置凭据,为什么我的侦听器无法进行身份验证?

1 个答案:

答案 0 :(得分:16)

首先,此消息通常表示计算机不在同一个域中,因此无法使用Windows安全性进行通信。这两个服务器是否在同一个域中?

其次,您已将端点配置为使用Windows安全性。您不仅在消息级别使用Windows安全性,而且在传输级别使用Windows安全性。两者看起来都有点矫枉过正,你可能只是想做运输。

第三,您配置的所有内容都显示“我想使用Windows身份验证”,但您正在设置ClientCredentials的UsernameClientCredentials属性。这些属性仅用于用户名令牌安全性,而不用于Windows。 Windows安全性将采用当前线程的身份并转发它。

假设您打算使用Windows安全性,那么您需要:

  1. 在您希望与订阅者进行通信的单个Windows身份下运行您的发布商流程。
  2. 在发布商流程中使用模拟更改每次调用的安全上下文(查看WindowsIdentity.Impersonate以获取更多信息)
  3. 现在你在技术上做#1,即使你认为你正在通过设置用户名/密码属性来做#2,因为它们被忽略了。

    最后,这里有一些关于如何为不同类型的Windows身份验证方案设置绑定的好文档:


    除此之外,如果没有您的更多信息,我不确定我能提供什么。如果你修改你的问题以提供更多信息/回答我的一些问题,我会很乐意修改我的答案,希望能使它更有用。