Silverlight using WCF with Windows Authentication

We all know it’s not possible yet to provide credentials when calling WCF Service. I’m telling yet, because I saw some signs that we might get support for credentials.

But what about now? Yes now, because Silverlight 3 isn’t release to the web yet.

Let’s think of all those applications that are running in the Intranet Zone for example. If they are built on the .NET environment, they often make use of Windows Authentication to authenticate the user. And after that make use of the roles assigned to the user to authorize the user.

But when we are working in the Silverlight environment we don’t really have the ability to make use of the User that’s already authentication against the Active Directory. But what about the services that Silverlight is using? Well that’s basically what this article is about.

Windows Authentication on WCF

A few days ago I read an article about Windows Authentication on WCF. This article explains the different steps to get Windows Authentication on WCF very well. But for the sake of this article I will summarize the steps that are required.

  1. Create your WCF Service
  2. Ensure authentication mode is Windows by adding <authentication mode="Windows" /> to the web.config
  3. Create the binding in the system.servicemodel element of the web.config just like this.
    <bindings> 
      <basicHttpBinding> 
        <binding name="BasicHttpEndpointBinding"> 
          <security mode="TransportCredentialOnly"> 
            <transport clientCredentialType="Windows" /> 
          </security> 
        </binding> 
      </basicHttpBinding> 
    </bindings>
  4. Make sure the WCF service configuration makes use of the binding created in step 3 by adding the following to the endpoint element for your WCF service.
  5. <endpoint … bindingConfiguration="BasicHttpEndpointBinding" />
  6. The article mentions to disable anonymous access and enable Windows Authentcation. But to make it work on Windows Server 2008 I had to make sure anonymous access was enabled as well.
    image
  7. If you want authentication to be automated you can do this easily by adding the url of your service to the local intranet zone.
  8. Just add a service reference like you would normally do from Silverlight.
  9. Create a very simple method to know if it’s working as expected. Something like:
    [OperationContract] 
    public string Hello() 
    { 
        // Add your operation implementation here 
        return string.Format("Hello, {0} at {1}", HttpContext.Current.User.Identity.Name, DateTime.Now); 
    }

And yes that just works. And this enables more things as well like ask if the user is in a specific role. Basically all the things you’re used to have access to in a Windows Authenticated ASP.NET application are available.

I think at least part of the credits for this article should go to Shivprasad koirala who wrote the Code Project article I refer to.

Let’s hope the next version of Silverlight enables credentials so we can make use of different authentication scenario’s as well.

Ps. This article is cross posted on: Mark Monster’s blog and Silverlight Help.

  • Gravatar Sam Bronchetti November 18th, 2009 at 22:45
    I have tried this, and still can't get it to work. Here is my situation...on my local machine if I use the default web server for VS2008, it appears that getting the user name using httpcontext.current.user.identity.name works fine. When I publish to the wweb server, if I remove anonymous authentication, the service doesn't work at all. If I have both anonymous and Windows Authentication, the method below fails.

    Here is my code in my wcf service:
    _
    Public Function GetCurrentStaffMember() As StaffMembers
    Dim userid As String = HttpContext.Current.User.Identity.Name.ToString.Substring(HttpContext.Current.User.Identity.Name.ToString.LastIndexOf("\") + 1)
    'userid = System.Security.Principal.WindowsIdentity.GetCurrent.Name
    'userid = userid.Substring(userid.LastIndexOf("\") + 1)
    'Dim userid As String = "sb1715"
    Dim staff As New StaffMembers
    Dim data As New DataClass
    Dim dr As DataRow = data.GetCurrentStaff(userid)
    staff.BusinessUnitID = dr("BusinessUnitID")
    staff.Staffid = dr("staffid")
    staff.StaffName = dr("Staff")
    staff.TeamID = dr("teamid")
    Return staff
    End Function
  • Gravatar Graeme January 22nd, 2010 at 13:58
    It is a sweeping statement to say that windows authentication works with silverlight as this is only partly true.

    If you are using silverlight to do a double hop i.e. calls a service on a server that calls a database on another server then it won't work as you cannot force silverlight to use Kerboros - this is required for the second hop - as it uses ntlm.

    Do you know if there is anyway round this? Have you tried this scenario before?

    Thanks
  • Gravatar Filipe February 23rd, 2010 at 18:20
    Great article but just to clarify if I have a silverlight app which calls a wcf service which in turn makes a call to sqlserver, will this work ? will sqlserver authenticate the credentials sent from the silverlight app (i.e. the web user)? or will sqlserver just be sent the credentials of the computer running the wcf service ? I have spent ages looking for a way to use windows authentication with the silverlight/wcf/sql combo so a definative answer for this would be massivly appreciated.
  • Gravatar Mark Monster February 23rd, 2010 at 22:27
    @Filipe

    Please be aware that this completely depends on the setup of the infrastructure. Standard NT networks won't let you reuse the token to the next server. You will need a Kerberos network for that. I don't know the exact details because I'm not a infrastructure specialist.
  • Gravatar Filipe February 24th, 2010 at 14:48
    Thanks for the fast reply Mark, this really helps alot.
  • Gravatar Marc April 2nd, 2010 at 04:21
    http://social.msdn.microsoft.com/forums/en-US/wcf/thread/df665f10-ea01-4f31-a944-555269f37d84/ might help for the double hop issue.
  • Gravatar Stephan April 11th, 2010 at 04:05
    I'm confused. (Sorry). First the article says it is not possible to pass credentials when calling a WCF service (presumably from SL). But then it goes on to show how you can configure the service so you get the Windows name. So what is the disconnect? Thanks
  • Gravatar Mark Monster April 13th, 2010 at 08:17
    @Stephan

    I understand the confusing. About the calling of a WCF service, we basically have no control of the exact credentials passed to this service.

    Though Windows Authentication is about the user already being authenticated through the network (most of the time) and the token achieved by logon is used for Windows Authentication as well. There's no control in here from the code-level in Silverlight.

    What I see quite often is that there are some 'public' services that require one specific set of credentials each time you call the service. This can't be used in conjunction with Silverlight. When you're working over the internet instead of intranet, it's even more a problem because you can't control the services you're calling.
  • Gravatar Lance April 28th, 2010 at 16:58
    The code for returning the user identity is not working for me. HttpContext.Current is null. I assume this is because the service is not running in asp.net compatibility mode.
  • Gravatar Graham Hobson February 15th, 2011 at 01:28
    The reason you needed Anonymous Authentication was for this line in the config



    The mex endpoint for downloading service proxies requires Anonymouse Authentication even when the Service is confgured for Winodws Authentication.
  • Gravatar Graham Hobson February 15th, 2011 at 01:29
    Sorry the line with the detail was removed, presumably becasue it had tag markers

    The reason you needed Anonymous Authentication was for this line in the config

    endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"

    The mex endpoint for downloading service proxies requires Anonymouse Authentication even when the Service is confgured for Winodws Authentication.
  • Gravatar Alex March 28th, 2011 at 08:46
    When I try Access webservice, I recevive next error.

    Security settings for this service require Windows Authentication but it is not enabled for the IIS application that hosts this service.

    How can I fix it?
  • Gravatar SilverLight-New-bee May 24th, 2011 at 00:28

    Hi Mark ,

    I am new to silverlight , but with experience with other .Net Apps. I am interested to know, how did you implement the right hand side --continous moving stuff . I am looking for this approach for my application.


    Well and good if you suggest or give me some code approach .

    Thanks

  • Gravatar Sam Bronchetti June 8th, 2011 at 15:16
    In my Silverlight service, this always always me to get the userid. This also strips off the domain prefix.

    Dim context As HttpContext = HttpContext.Current
    If userid = "" Then
    userid = context.Request.ServerVariables("AUTH_USER").Substring(context.Request.ServerVariables("AUTH_USER").LastIndexOf("\") + 1)
    End If
Gravatar