[Updated for Win8/Dev11 Beta]
This is an extension to my earlier post – http://blogs.msdn.com/b/piyushjo/archive/2011/10/10/calling-a-wcf-service-from-a-metro-application.aspx where I did a walkthrough of calling a WCF service hosted locally on the same machine from a C# Metro client application. In this post, I’ll take you through how to add security.
As you will remember, I had a Picture REST service with webHttpBinding and a ViewCount SOAP service.
Below is a refresher on how to add security to the binding and configuring the respective service hosts with these bindings.
I am going to use my domain credentials and so I have configured my bindings with SecurityMode of TransportCredentialOnly and HttpClientCredentialType of Windows.
Once you have made the above changes to the service, you need to start up the service host and export metadata for the SOAP service so that we can add service reference to it. When you have completed the Add Service Reference (ASR) action from the metro client application, you will see the following now modified GetBindingForEndpoint method generated on the client (in Reference.cs file, if you do ‘Show all files’ on the added service reference) which as you can see is already configured for security.
If you are doing this from a non-metro client then equivalents of lines 5 and 6 get generated in xml configuration but since there is no xml styled configuration for metro application, the WCF ASR experience is intelligent enough to generate the equivalent code.
The above code configuration will enable the proxy to call the SOAP web service providing default domain credentials and you do not have to write any additional piece of code other than instantiating the proxy as we were already doing.
That takes care of the SOAP service.
Now for the REST service, we need to configure our HttpClient, which we were using to access the service, to pass the credentials. Here is how you do it:
You need to instantiate an HttpClientHandler object, configure it to use the default credentials and provide it to the HttpClient so that HttpClient knows that when it gets back an HTTP status code 401 from the service with request for credentials, it needs to pass the default domain credentials.
And finally, before running the metro client, don’t forget to enable the “Default Windows Credentials” capability which will allow the metro client to retrieve the required domain credentials:
I have modified my REST and SOAP service methods to print the domain credential name passed to the service (using OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name) so you know that the credentials are getting passed correctly!
Sample code attached: