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 (https://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.
So where does that leave us with the client OM and claims? Well it is doable. The really difficult scenario, the one I’m talking about in this post is using the.NET Managed Code client OM. If you are using SilverLight or Javascript you should have the credentials you need from the browser and everything flows back and forth. From something like a Windows or console application you essentially need to do is get the same authentication cookie you get when you visit a claims based auth site in the browser, and attach it your client OM request.
UPDATE
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.
UPDATE #2
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.
UPDATE #3
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 https://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
Comments
Anonymous
January 01, 2003
thanksAnonymous
January 01, 2003
The comment has been removedAnonymous
February 28, 2011
Wow, i tried to do this once using browser control using and listening to load events ... but that was very messy .. this is perfect... thanks for all your efforts :DAnonymous
November 18, 2011
It's OK for .net libraries. What is about Silverlight? How to connect the SharePoint from the Silverlight application hosted outside SharePoint. I have confgigured clientaccesspolicy file. But I get "Not found" error. Look into log with fiddler I figured out that it couldn't authenticate to sites.asmx service.Anonymous
June 27, 2012
Thanks that is very helpful! I will be using this as a starting point. Question. Is there a way to extract the ADFS url from SharePoint instead of asking the user to provide? SharePoint server should have that already so it would be nice not asking user.Anonymous
July 03, 2012
It worked for me while I have ADFS 2.0 on Windows 2008 with SP2. So as per your update#3, does that exception occurs in some certain scenario with Windows 2008?Anonymous
March 22, 2013
Hi, We have SharePoint 2010 hosted on custom Online Services with ADFS2.0 claims Authentication. I am able to get SecurityToken from ADFS using SOAP request. But while connecting to SharePoint site with HttpWebRequest, I do get response with “webResponse.StatusCode=Found” but CookieCount=0. Does anyone knows how to get CookieCollection for SharePoint site with ADFS authentication? How to get ‘FedAuth’ cookie using HttpWebRequest? Reference Used: For Security Token: leandrob.com/.../request-a-token-from-adfs-using-ws-trust-from-ios-objective-c-iphone-ipad-android-java-node-js-or-any-platform-or-language For SharePoint Authentication: fredericloud.com/.../connecting-to-sharepoint-with-claims-authentication My above mentioned issue is for SharePoint hosted on our online service with ADFS2.0. I have followed Whitepaper (see below link) published by Microsoft except 1 thing. In white paper sample code (page 89) they have used ADFS/services/trust/2005/windowstransport but I have used ADFS/services/trust/2005/UsernameMixed. Whitepaper asked to enable windowstransport node. Here I think I have to enable UsernameMixed node too. UsernameMixed node on ADFS server is already enabled. download.microsoft.com/.../oit2010-whitepaper-claims-based-authentication.pdfAnonymous
October 28, 2013
Hi Steve, Have you got chance to test this version of code for SharePoint 2013? Does it really work? I have tried but it throws an error. Thank you.Anonymous
December 12, 2013
Kasim, Were you able to make this example work for SharePoint 2013? Thanks,Anonymous
February 28, 2014
Hi guys,,, I have same scenario as Aleksei Kachanov. where I have Silverlight application which is hosted outside the sharepoint in a claims aware .asp.net app. I have added client access policy at root of claims authenticated sharepoint site.still I am not able to access client object model. I am getting same error "Not found" and in fiddler it shows error on sharepoint sites layouts/Authenticate page with no message in fiddler.
Any help guys..................Anonymous
August 15, 2014
upon executing the example, with fiddler i get the following error: The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate' Then when i click ok Fiddler pops up a message asking if i want to ignore remote certificate error?
A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.
SUBJECT: CN=localhost
I then ignore errors and proceed anyways. the server then responds with a 403 status code.
Then when i turn Fiddler off I get the following Error:
The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
I have ADFS supplying tokens for users that access sharepoint 2013 directly and now i am trying to enable my C# application to gain access.Anonymous
September 18, 2014
The comment has been removedAnonymous
February 28, 2015
NOTE: This posting is a very small part of one section of a new whitepaper coming out on claims and SharePoint