Posts Tagged ‘wcf’
Posted on March 12, 2009 - by Rouslan Grabar
20 steps to get together Windows Authentication, Silverlight and WCF service
For one of my projects I had to query WCF web service for some data and display it in the Silverlight powered client. The web service should return data relevant to the identity of the person, querying the service with the Silverlight client. The choice of Silverlight over other technologies has been made to meet requirements for rich interface, consisting of the flexible grid with grouping, sorting and filtering. Pretty much the same grid as the one you may be looking at every day while using Microsoft Outlook. Since the application should be used inside the corporate intranet, one of the requirements was the usage of integrated Windows authentication,
I started experimenting with WCF service project template in Visual Studio. The only method of the new web service was supposed to return login name of the current user, but ServiceSecurityContext.Current.WindowsIdentity.Name was not available at all (the context was null).
Googling for the solution brought advices about using the ASP.NET services with Form Authentication, which effectively renders usage of the Active Directory useless.
To make long story short here are the steps:
- Create Silverlight Project

- Choose to have the Visual Studio create a web site to host the Silverlight application

- Select the created web site and add Silverlight enabled WCF service to it.

- Open web site project properties and on Web tab, select Create Virtual Directory

- Start IIS management console and edit newly created directory’s security settings. You have to disable anonymous access and make sure you have Windows authentication selected

- Open ASP.NET tab and edit Authorization configuration – Deny access for anonymous users for all requests

- Restart IIS - sorry, no picture here :)
- Now time to implement DemoService.svc
using System.ServiceModel; using System.ServiceModel.Activation; namespace RouslanComDemoApp.Web { [ServiceContract(Namespace = "")] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class DemoService { [OperationContract] public string GetWindowsUsername() { return ServiceSecurityContext.Current.WindowsIdentity.Name; } } } - Open Web.config and locate section <system.ServiceModel>. Replace the entire section with the following directives:
<system.serviceModel> <bindings> <basicHttpBinding> <binding name="winAuthBasicHttpBinding"> <security mode="TransportCredentialOnly"> <transport clientCredentialType="Windows"/> </security> </binding> </basicHttpBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="RouslanComDemoApp.Web.DemoServiceBehavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> </behaviors> <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> <services> <service behaviorConfiguration="RouslanComDemoApp.Web.DemoServiceBehavior" name="RouslanComDemoApp.Web.DemoService"> <endpoint address="" binding="basicHttpBinding" bindingConfiguration="winAuthBasicHttpBinding" contract="RouslanComDemoApp.Web.DemoService" /> </service> </services> </system.serviceModel>
- Make sure that project builds and try to open DemoService.svc in browser

- Now we can get back to the Silverlight client app, that should consume the service we have just created. So lets add the service reference to the Silverlight project.

use the Discover button to use the service in our solution

- Now open Page.xaml and replace the contents with the code snippet below
using System.Windows; using RouslanComDemoApp.DemoServiceReference; namespace RouslanComDemoApp { public partial class Page { public Page() { InitializeComponent(); } private void QueryServiceButton_Click(object sender, RoutedEventArgs e) { DemoServiceClient ws = new DemoServiceClient(); ws.GetWindowsUsernameCompleted += ws_GetWindowsUsernameCompleted; ws.GetWindowsUsernameAsync(); } void ws_GetWindowsUsernameCompleted(object sender, GetWindowsUsernameCompletedEventArgs e) { UserNamePlaceHolder.Text = e.Result; } } } //please note, the code above does not use error checking for clarity - Build and run the application.
- You should now get nothing but the empty blank IE screen with little yellow warning sign in bottom left corner, which is there to say, that the Silverlight could not be loaded.

- To fix this problem you have to tell IIS about Silverlight mime type. It does not know that files with .xap extension should be served with application/x-silverlight-app content type header.

- Now if you run the application once again, you will be presented with one more obstacle. This time friendly and informative Visual Studio exception window tells you something about missing access policy.

So let’s have one in place. Create file clientaccesspolicy.xml and put in there the following XML. Please note this is a sample policy and should not be used as is in production environment!<?xml version="1.0" encoding="utf-8" ?> <access-policy> <cross-domain-access> <policy> <allow-from> <domain uri="*"/> </allow-from> <grant-to> <resource include-subpaths="true" path="/"/> </grant-to> </policy> </cross-domain-access> </access-policy>
- Place the XML file in to web server root folder and start the client application again.
- Now the application should start and you should be able to see the cute minimalistic design of our client app.

- Press the Query Service button and wait for breakpoint to trigger (here I assume you have set it up in advance)

- Well done, we have working client consuming WCF web service using Windows Integrated Authentication!

PS: In case you happen to host your web service in a web site located inside your “My Documents” folder, then you should update NTFS permissions for web site folder so authenticated users could access it.

Please leave feedback! Thank you.

