Monday, October 6, 2014

Migrating from WCF MessageSecurity with custom username/password to TransportSecurity with custom username/password

In performing a migration from WCF MessageSecurity with custom username/password to TransportSecurity with custom username/password, I learned some things the hard way. So they are therefore documented here.

First, TransportSecurity does not support custom username/password. If you try to use TransportSecurity with clientCredentialType="Basic", you get an exception "The HTTP request is unauthorized with client authentication scheme 'Basic'. The authentication header received from the server was..."So you need to use "mixed mode", which is configured like this:
<security mode="TransportWithMessageCredential">
      <message clientCredentialType="UserName"/>
 </security>
Good links to study more on this are here and here.

When doing this migration, if you have been using a test certificate, it might not suit its new use. The test certificate for TransportSecurity should be created with a locally-created CA (Certificate Authority). Also, the name of the certificate (CN/SubjectName) must be the same as the service domain (for example service1.hunterhrms.com), otherwise you get an exception "The remote certificate is invalid according to the validation procedure".
So create your test certificate according to this link. Note that the test certificate does not have to be installed on the client, only the CA.
To complement the data in the above link:

To create the certificates, open a cmd window as administrator and navigate to Microsoft SDK's bin folder.
From there, to create the CA run something like:
> makecert -n "CN=NiloosoftCA" -r -sv NiloosoftCA.pvk NiloosoftCA.cer

To create the test certificate, run something like:
> makecert -sk service1.hunterhrms.com -iv NiloosoftCA.pvk -n "CN=service1.hunterhrms.com" -ic NiloosoftCA.cer -sr localmachine -ss my -sky exchange -pe 
You can write "CN=*.hunterhrms.com" instead of the "CN=..." above, to allow the certificate to be used on all services with the given domain (wildcard certificate). Otherwise, you would need to create a separate test-certificate for each service. 

Service Configuration:
In the service behaviour, no need for the <serviceCertificate> element under <serviceCredentials> - the certificate is set on the IIS site's https binding (just like any https site).

Client-side client endpoint configuration:
I haven't found the <identity> element to be of any meaning.
Also, in the endpoint behaviour, no need for the <serviceCertificate> element under <clientCredentials>. Looks like the client simply checks the server's certificate against an existing Certificate Authority.

The writer is R&D team leader at Niloosoft Hunter HRMS

No comments:

Post a Comment