«

»

Feb 04

Claims Proxy – A C# Library for Calling Claims Protected Web Services

The ClaimsProxy library enables you to get a WIF cookie collection for a SharePoint site which is protected by Claims Based Authentication. It assumes that ADFS is configured as the Trusted Identity Token Issuer and that the down-stream identity provider is based on the StarterSTS / IdentityServer project.

In some recent work I needed to call some SharePoint 2010 web services from a client outside of the SharePoint farm.  Using traditional network credentials and Windows Authentication this was a straightforward matter, for example:


ICredentials credentials = new NetworkCredential('username', 'password', 'domain');
SharepointUserGroupsWCF.UserGroupSoapClient client = new SharepointUserGroupsWCF.UserGroupSoapClient();
client.ClientCredentials.Windows.ClientCredential = (NetworkCredential)credentials;
client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
client.Endpoint.Address = new EndpointAddress(webPath + "/_vti_bin/usergroup.asmx");

XElement groupXml = client.GetGroupCollectionFromSite();

However, when the target service is protected by Claims Based Authentication, it’s not so straightforward to call such services.  In my scenario I had a SharePoint 2010 site protected in a web application configured with Claims Based Authentication.  I had configured SharePoint to direct authentication to ADFS (Microsoft Active Directory Federation Server), and then I had a custom claims provider configured based on Dominick Baier’s Identity Server  open source STS product (formerly StarterSTS), however my approach could easily be adapted to work with any number of final claims providers.

Even if you just want the code, read this bit first.

I’ve implemented the code as a .NET 4.0 assembly, although it should be relatively easy to get it to compile under .NET 3.5.  The overall approach works as follows:

  • Use username + password to request a symmetric token from our custom STS (you could get a Windows token here or whatever you are using) – set the realm to that configured for ADFS
  • Use that token to request a bearer token from ADFS – set the realm to the SharePoint site realm as configured in ADFS
  • Use the token from ADFS to authenticate with SharePoint
  • From the resulting authentication response, extract the WIF (Windows Identity Foundation) cookie for authentication (commonly named FedAuth)
  • Return this cookie to the client

I have included a test application in the solution which demonstrates using the returned cookie to make a call to a web service in the SharePoint site.  I’ve left the responsibility of caching the cookie to the client (but included this in the test app).

IMPORTANT NOTE: There is one modification required to the library which I haven’t done yet.  If you read the finer details of WIF you will know that if the SAML token data is too large for a single cookie, then WIF spreads the data over multiple cookies named FedAuth1, FedAuth2 … FedAuthN.  The library assumes that there is only one FedAuth cookie at present – which will be sufficient for most applications – but its worth keeping an eye on if you’re running into troubles.  I will get around to sorting this at some point, but feel free to make a pull request on my Github repository if you get there first.

Download the ClaimsProxy library and sample application from Github

ClaimsProxy is straightforward to use:


// configure our SPServiceRequestor.
var requestor = new SPServiceRequestor
{
    DobstsEndpoint = "https://startersts.yourdomain.com/startersts/users/issue.svc/mixed/username",
    DobstsUsername = "joe.bloggs@yourdomain.com",
    DobstsPassword = "password",
    DobstsAdfsRealm = "https://adfs.yourdomain.com/adfs/ls/",
    AdfsEndpoint = "https://adfs.yourdomain.com/adfs/ls/",
    SharepointRealm = "urn:sharepoint:sp.yourdomain.com",
    SharepointSiteUrl = "https://sp.yourdomain.com/",
    IgnoreSslValidation = true,
    DebugMode = true,
    DebugEventCallback = (data) =>
    {
     // your debug function here
    }
};

string spCookieRaw = requestor.GetCookie();

N.B.: DobSts is our own implementation of the StarterSTS project.

Check out the sample application for a full example of how to use the library.

I’d welcome any comments / feedback on this – hopefully it will be of some use to others out there, it certainly has been to me.

Permanent link to this article: http://www.huggill.com/2012/02/04/claims-proxy-a-c-sharp-library-for-calling-claims-protected-web-services/

7 comments

Skip to comment form

  1. John

    Your code is not available to download. Has it been disabled?

    1. shuggill

      Hi John I just checked the GitHub link and everything appears to be working OK. Try it here: https://github.com/shuggill/ClaimsProxy

  2. Abhay

    I have a similar requirement as yours – using a claims aware WCF service with clients – ASP.Net and SharePoint (both SAML 2.0 claims aware). I am trying to host this service within SharePoint, which prevents me of doing any configurations in the WCF to handle claims for authentications since SharePoint takes care of it.
    I am able to hit this service and pass the claims using SP client, but not getting the correct conifiguration and client side code to be used for ASP.Net client(claims aware).
    Can you suggest where I am going wrong?

    Below is my web.config:

    The SharePoint client call is like:
    string endpointConfiguration = string.Format(“GRRCustomBindingService{0}”, serviceHost.Scheme);
    _channelFactory = new CustomConfigurationChannelFactory(endpointConfiguration, ClientConfig, endpointAddress);
    _channelFactory.ConfigureCredentials(SPServiceAuthenticationMode.Claims);
    _channelFactory.Open();

    if (impersonateUser)
    _channel = SPChannelFactoryOperations.CreateChannelAsProcess(_channelFactory, endpointAddress);
    else
    _channel = SPChannelFactoryOperations.CreateChannelActingAsLoggedOnUser(_channelFactory, endpointAddress);
    _channelComObj = (ICommunicationObject)_channel;

    _channelComObj.Open();

  3. Abhay

    Also, not sure why are you using a custom STS. and not ADFS directly?

    1. shuggill

      We needed a custom STS as our user store is in a proprietary SQL database. However if you’ve got your users in Active Directory, then you only need ADFS.

  4. pat

    Hi Sam, is it possible to to get a cookie collection for a SharePoint site which is protected by Claims Based Authentication with custom STS without using ADFS?

    1. shuggill

      Hi Pat,

      Yes this is certainly possible. All you need to do is modify the code to talk to your custom STS (whatever that may be) and get the initial token from there, and then request a SharePoint cookie using it.

      In my code example I’m talking to a custom STS called StarterSTS – you can use that code to talk to your custom STS, skip the ADFS bit and then do the final part of getting a cookie from SharePoint.

      HTH,
      Sam

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>