WCF: The request for security token could not be satisfied because authentication failed
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?
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:
- Run your publisher process under a single Windows identity you want it to be communicating with the subscribers as.
- 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:
- Transport Security with Windows Authentication
- Message Security with Windows Client
- Message Security with Windows Client without Credential Negotiation
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.
精彩评论