Authentication failed between client and WCF service
This a question that already has been discussed a couple of times on SO but I couldn't find any suitable solution to my problem. I have a WCF service hosted on an external server (other domain) and I'm trying to consume it from a command line application. I receive the following error:
The request for security token could not be satisfied because authentication failed.
The service is configured inside a web.config file:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBinding_IRun">
<security mode="None">
<message clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="http://www.domain.net"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
<behaviors>
<serviceBehaviors>
<behavior name="calculadora.SOA.RunBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="calculadora.SOA.RunBehavior" name="calculadora.SOA.Run">
<endpoint address="http://www.domain.net/calculadora/SOA/run.svc" binding="wsHttpBinding" contract="calculadora.SOA.IRun">
<identity>
<dns value="domain.net"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
On the client side, I create a custom binding to connect to the service. Here is the security configuration:
standardBinding.Security.Mode = SecurityMode.None;
standardBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
standardBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialT开发者_如何学Goype.None;
standardBinding.Security.Transport.Realm = "";
standardBinding.Security.Message.ClientCredentialType = MessageCredentialType.None;
standardBinding.Security.Message.NegotiateServiceCredential = false;
standardBinding.Security.Message.EstablishSecurityContext = false;
standardBinding.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Default;
I'm not using any security mechanism for authentification but still, the service seems to be expecting one. When working on different domains, is it mandatory to use a basic authentification?
EDIT: I wasn't referencing any binding configuration at my endpoint. Once the reference was set, I received another message error:
{"The message with Action 'http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue' cannot be processed at the
receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract
mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the
receiver. Check that sender and receiver have the same contract and the same binding (including security
requirements, e.g. Message, Transport, None)."}
The issue was caused by my client's binding. While I was creating my custom binding using the standard 'WSHttpBinding', the 'SecurityMode' property was set to 'Message' instead of 'None'. Now the code looks like the following and the service finally works:
WSHttpBinding standardBinding = new WSHttpBinding(SecurityMode.None, false);
CustomBinding myCustomBinding = new CustomBinding(standardBinding);
Many thanks to marc_s!
I think the problem is your service endpoint definition:
<endpoint address="http://www.domain.net/calculadora/SOA/run.svc"
binding="wsHttpBinding" contract="calculadora.SOA.IRun">
You are using the standard wsHttpBinding - which defaults to integrated Windows security as message security.
While you do define a binding configuration (called wsHttpBinding_IRun
), you're not referencing it in your endpoint definition - thus it doesn't come into play. You need to extend your service endpoint definition with a bindingConfiguration
attribute like so:
<endpoint address="http://www.domain.net/calculadora/SOA/run.svc"
binding="wsHttpBinding"
bindingConfiguration="wsHttpBinding_IRun"
contract="calculadora.SOA.IRun">
in order to actually use your defined binding configuration (including the security settings).
I ran into the same issue and after a whole day invested, finally I figure out how to fix. The key is put establishSecurityContext="false" into message tag.
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="UserName" establishSecurityContext="false" />
</security>
精彩评论