Tuesday, November 11, 2008

Autheticating HTTP Basic Authentication with X509 Certificate on SSL Web Service On WCF

This takes me quite awhile to figure out how to get it done on WCF. My requirement is I need to construct a client to connect to a web service with X509Certificate and HTTP Basic Authentication is needed to authenticate myself to web service. This is dual authentication mechanism. Although I can find out how to use X509 Certificate relatively easy it took me some time to play around with my config file to get the HTTP Basic Authentication correct. Here's what I did

First, I need to get the x509 behavior declare under

<behaviors>
<endpointbehaviors>
<behavior name="X509DigiCert">
<clientcredentials>
<clientcertificate findvalue="Myx509Cert" storelocation="CurrentUser" x509findtype="FindBySubjectName">
<servicecertificate>
<authentication certificatevalidationmode="None">
</servicecertificate>
</clientcredentials>
</behavior>
</endpointbehaviors>
</behaviors>

Next I need to create my own custom binding. You need to specify authenticationScheme="Basic" for Basic Http Authentication and requireClientCertificate="true" to tell WCF we are using X509 Certificate.


<!-- Use custom binding for HTTP Basic Authentication + X509 Certificate Authentication.-->
<custombinding>
<binding name="OtherPublishedDataWebServiceServiceSoapBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00"
sendTimeout="00:01:00" >
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
messageVersion="Soap11" writeEncoding="utf-8">
<readerQuotas maxDepth="100000" maxStringContentLength="100000"
maxArrayLength="67108864" maxBytesPerRead="65536" maxNameTableCharCount="100000" />
</textmessageencoding>
<httpsTransport manualAddressing="false" maxBufferPoolSize="67108864"
maxReceivedMessageSize="67108864" allowCookies="false" authenticationScheme="Basic"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="67108864" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" requireClientCertificate="true" />
</binding>
</custombinding>

Lastly, identify endpoint and make sure you include behaviorConfiguration with the previously declared behavior name X509Digicert and for binding configuration use the custombinding that we have create above. It should look something similar to this.

<endpoint address="https://mywebservices.com/OtherPublishedReports"
behaviorConfiguration="X509DigiCert" binding="customBinding"
bindingConfiguration="OtherPublishedDataWebServiceServiceSoapBinding"
contract="OtherPublishedReports.OtherPublishedDataWebService"
name="OtherPublishedDataWebServiceServiceSoapBindingQSPort" />

For Basic HTTP Authentication User Name and Password you have to include in your code. Sample code snippet below.

Dim report As OtherPublishedReports.OtherPublishedDataWebServiceClient = New OtherPublishedReports.OtherPublishedDataWebServiceClient()
'Adding Credential
report.ClientCredentials.UserName.UserName = "User"
report.ClientCredentials.UserName.Password = "Password"

No comments: