I want to connect to a service web service, using WCF, that uses certificates for authentication is message level.
I currently have this configuration in App.config:
<basicHttpBinding>
<binding name="SomeServiceHttpsBinding">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="Certificate" />
</security>
</binding>
</basicHttpBinding>
and this binding is specified in the endpoint of the service.
The connection is fine, and the request is sent, accepted and responded by the server, but the server does not include any security header in its response (I checked the actual response with a proxy debugger). So I get this exception:
An unhandled exception of type 'System.ServiceModel.Security.MessageSecurityException' occurred in mscorlib.dll
Additional information: Security processor was unable to find a security header in the message. This might be because the message is an unsecured fault or because there is a binding mismatch between the communicating parties. This can occur if the service is configured for security and the client is not using security.
I found that I have to change the binding type from <basicHttpBinding> to <customBinding> and add the attribute enableUnsecuredResponse="true" to it for solving this problem. But it has a lot of complicated options that confuses me and I don't know how can I do the same here.
Now the question is, how can I write the equivalent of the settings above, in <customBinding> format and so I can use enableUnsecuredResponse too?
I found another way to solve my almost similar problem (done by code, not by config and for BasicHttpsBinding). It's a solution based on a SOAP Message with username/password (in order to get a sample easy to test)
private static ChannelFactory<T> CreateSecureChannel<T>(string url, string username, string password)
{
var binding = new BasicHttpsBinding
{
MessageEncoding = WSMessageEncoding.Text,
UseDefaultWebProxy = true,
BypassProxyOnLocal = false,
Security =
{
Mode = BasicHttpsSecurityMode.TransportWithMessageCredential,
Transport =
{
ClientCredentialType = HttpClientCredentialType.None,
ProxyCredentialType = HttpProxyCredentialType.None
},
Message =
{
ClientCredentialType = BasicHttpMessageCredentialType.UserName,
AlgorithmSuite = SecurityAlgorithmSuite.Default
}
}
};
var channel = new ChannelFactory<T>(binding, new EndpointAddress(url));
var elements = binding.CreateBindingElements();
elements.Find<SecurityBindingElement>().EnableUnsecuredResponse = true;
var customBinding = new CustomBinding(binding);
customBinding.Elements.Clear();
customBinding.Elements.AddRange(elements.ToArray());
channel.Endpoint.Binding = customBinding;
channel.Credentials.UserName.UserName = username;
channel.Credentials.UserName.Password = password;
return channel;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With