We are writing a client to a WCF service that uses both a CSR certificate and basic authentication.
Our C# client is generated via Visual Studio and we can programmatically set the certificate and the username/password. However, we have to manually send the Basic Auth header otherwise we receive the error:
'The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Basic realm="HttpBasicAuthentication"'.'
Our code is:
var myBinding = new WSHttpBinding();
myBinding.Security.Mode = SecurityMode.Transport;
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
myBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
var ea = new EndpointAddress("https://example.org/myservice");
var client = new MandateWebServiceClient(myBinding, ea);
client.ClientCredentials.UserName.UserName = "wally";
client.ClientCredentials.UserName.Password = "walliesWorld";
client.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2("C:\\some\\path\\to\\csr.pfx", "password");
using (var scope = new OperationContextScope(client.InnerChannel))
{
var httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers[HttpRequestHeader.Authorization] =
"Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(client.ClientCredentials.UserName.UserName + ":" + client.ClientCredentials.UserName.Password));
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
client.create();
}
With the above code, we can successfully talk to the service. If we remove the lines in the using
block, the authentication scheme changes to Anonymous
, and we get the error above.
The above arrangement seems a little hackey. We have tried all the SecurityMode
settings possible and SecurityMode.Transport
with HttpClientCredentialType.Certificate
is the only combination that allows the certificate to be accepted. Setting or not setting MessageCredentialType.UserName
appears to have no effect on the system.
Is there any .Net Framework way of providing both the certificate and the basic authentication header rather than manually adding the header?