Using the Client Object Model with a Claims Based Auth Site in SharePoint 2010
This is a companion posting to my blog about how to use the client OM with a site that is secured with FBA (http://blogs.technet.com/b/speschka/archive/2010/06/03/using-the-client-object-model-with-a-forms-based-auth-site-in-sharepoint-2010.aspx).
First let me just say, this was hard! Like probably way harder than you would hope for, but there is actually a pretty understandable reason why that’s the case. With both Windows and forms based authentication you have a very well understood set of standards for how the authentication process is done. That’s why out of the box you will find the client OM “just works” when you are logged into a Windows workstation and hit a Windows-secured site, and also why you find support for forms based authentication out of the box. So why not out of box support for claims too in the client OM? Well the reality is that with claims there are about a million and one different directions you can take it. Any given identity provider along the way can choose to redirect you, prompt you for credentials, prompt you for a secret key (like two-factor authentication), etc. So there really isn’t a fixed set of hoops you have to jump through to get authenticated.
I've worked with Slava to get a version of this working that uses WIF to talk directly to an ADFS server to get the FedAuth cookie that SharePoint requires. I've left the old code in the sample application but replaced what is called with the new code that gets the FedAuth cookie directly. There is one thing that's important to note about the new code sample however. For ADFS v2, it does require you to make a change in the configuration from the default settings on the ADFS server. Specifically you need to enable the adfs/services/trust/13/windowstransport endpoint. To do that you need to go to your ADFS v2 server and do the following:
- Open the AD FS 2.0 Management application
- Expand the Service node and click on the Endpoints node
- Right-click on the /adfs/services/trust/13/windowstransport node and click on Enable on the shortcut menu
- Restart the AD FS 2.0 WIndows Service
From a code perspective, to use this now you need the Url to the root of the ADFS server in addition to the Url to the site collection in SharePoint. Rather than try to explain the new WIF code, which I can't really do well since I'm not a WIF expert, I'll just defer to the source code and let you browser through it. A couple of notes for your own implementations though:
- Make sure you add the WcfClientContracts13.cs class to your project.
- Make sure you add the RequestBodyWriter.cs class to your project.
- To get the reference to XmlDictionaryReader you need to add a reference to System.Runtime.Serialization.
That should be enough to get you going. I've attached the updated zip to this post.
I updated the code again to use the WS-Trust 1.3 protocols and endpoint. The Feb. 2005 version being used previously was an interim body of work prior to the 1.3 standard being agreed upon. The code sample and instructions here now use the official standard.
You may experience an error when trying to retrieve the SAML token from ADFS; for example, you may have an exception thrown that reads something like "The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate oW0wa6ADCgEBomQEYmBgBgkqhkiG9xIBAgIDAH5RME+gAwIBBaEDAgEepBEYDzIwMTEwODA1MjA1MTMzWqUFAgMDdRemAwIBKakPGw1DT05UT1NPLkxPQ0FMqhMwEaADAgEBoQowCBsGcG9ydGFs'." Unfortunately, despite working on this for several hours, the only work-around I found was to
- Upgrade the ADFS server to Windows Server 2008 R2 (tips for doing so are described at http://blogs.technet.com/b/speschka/archive/2011/08/09/tips-for-upgrading-or-moving-adfs-2-0.aspx)
- Going into the IIS Management snap-in on the ADFS server and
- Drilling down into the Default Web Site/adfs/ls virtual directory
- Double-click on the Authentication icon in the middle pane
- Click on Windows Authentication
- If the status isn't Enabled then enable it
- Click on Advanced Settings in the right pane
- Under Extended Protection select "Accept" from the drop down and save your changes