WCF:由于身份验证失败,无法满足安全令牌的请求

发布于 2024-08-09 19:56:34 字数 2311 浏览 3 评论 0原文

我在同一台机器上有两个 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 身份验证。

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

I have two WCF services on the same machine. One is the publisher and one is the listener.

The Publisher is dynamically creating proxies based upon and endpoint. I am configuring the proxy in code like this:

            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;

and then...

            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));

When I go to make my call I receive the above error. Here is my listener config file:

   <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>

I have checked all my ACL on the directories that host the services and they appear to be correct. IIS security is set to Anonymous access and Windows Authentication.

So if I am explicitly setting the credentials in code, why can't my listener authenticate?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

柳若烟 2024-08-16 19:56:34

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

其次,您已将端点配置为使用 Windows 安全性。您不仅在消息级别使用 Windows 安全性,而且还在传输级别使用 Windows 安全性。两者似乎都太过分了,你可能只是想进行运输。

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

假设您的意图是使用 Windows 安全性,那么您需要:

  1. 在您希望它与订阅者进行通信的单个 Windows 身份下运行您的发布者进程。
  2. 在发布者进程中使用模拟来更改每个调用的安全上下文(请查看 WindowsIdentity。模拟 了解更多信息)

现在,从技术上讲,您正在执行#1,即使您认为通过设置用户名/密码属性正在执行#2,因为它们会被忽略。

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


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

First, this message usually means the machines aren't on the same domain and, thus, can't communicate using Windows security. Are the two servers are on the same domain?

Second, you've configured your endpoint to use Windows security. You using Windows security not only at the message level, but at the transport level. Both seems like overkill, you probably just want to do transport.

Third, everything you have configured says "i want to use Windows authentication", but then you are setting the UsernameClientCredentials properties of the ClientCredentials. Those properties are only used for Username token security, not Windows. Windows security is going to take the identity of the current thread and forward it on.

Assuming your intention was to be using Windows security, then you either need to:

  1. Run your publisher process under a single Windows identity you want it to be communicating with the subscribers as.
  2. Use impersonation within the publisher process to change the security context for each call (look into WindowsIdentity.Impersonate for more info)

Right now you are technically doing #1 even if you think you're doing #2 by setting the username/password properties since they are being ignored.

Finally, here's some good documentation on how to setup your bindings for different kinds of Windows authentication scenarios:


Beyond this, I'm not sure what else I can give without more information from you. If you revise your question to provide some more info/answer some of my questions I will gladly revise my answer to hopefully make it more useful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文