With the release SharePoint in 2013 and the ever increasing numbers taking up the SharePoint Online offering, it’s a good time to start looking at some of the challenges when moving to these platforms.
SharePoint has traditionally been a presentation technology with its own unique SharePoint development model utilising SharePoint designer and custom Web Part development. With the latest release, SharePoint 2013 that development model has been challenged by a new autonomous development model where the complexities and constraints of SharePoint as a development and deployment platform has been replaced by a service oriented integration platform for multiple independently hosted applications.
SharePoint has always supported a rich and expanding set of services with every release. As part of the move to the new development model a lot of work has gone into improving the “Client side” access into SharePoint by wrapping services in client side APIs and delivered some as easy to consume REST/oData endpoints, but the functionality of those services is still limited and has not yet evolved to match the power of the native SharePoint Server API nor the native SharePoint Web Services.
When moving from an on-premise SharePoint to SharePoint Online web service clients that were previously written against SharePoint Web Services (like UserProfile.asmx or Lists.asmx) will stop working because the authentication model has changed. A web service client that previously used Active Directory accounts to access SharePoint will need to become “claims aware” to use SharePoint Online. This involves syncing active directory accounts up to the MS Online Active Directory and authenticating at the MS Online Security Token Service (STS) before accessing SharePoint.
We hit this problem where a client had built a set of jobs, utilities and components that request and update SharePoint through services which then broke when migrating to SharePoint Online. The solution to updating these clients is well covered by this blog by Wictor Wilén. What this involves is opening up the source code for each client and inserting the appropriate authentication code using the MSOnlineClaimsHelper to do get the authentication cookies before calling the service.
The problem is we really didn’t want to pick through someone else’s code and find all the places to insert the authentication code. Surely there is an easier way to inject this boilerplate code without having to recode all the clients? Turns out there is, if those clients are written using WCF. What we can do is write a WCF Client side behaviour to detect when authentication needs to be done, make the appropriate requests to MS Online STS, attach the cookies and then allow the SharePoint service request proceed as normal.
To use the ClaimsHelper, first set up the Uris of the SharePoint resources you want to access and the corresponding username/passwords using a CredentialCache and set it to the MsOnlineClaimsHelper.CredentialCache.
CredentialCache credentialCache = new CredentialCache();
credentialCache.Add(_hostUri, “Basic”, new NetworkCredential(“peter.reid@kloud.com.au”, “blah”));
MsOnlineClaimsHelper.CredentialCache = credentialCache;
Then there are two ways to use this library. Either manually request the cookies or attach to the outgoing request like this:
UserProfile.UserProfileServiceSoapClient userProfile = new UserProfile.UserProfileServiceSoapClient(“UserProfileServiceSoap”, _hostUri + “_vti_bin/userprofileservice.asmx”);
using (new OperationContextScope(userProfile.InnerChannel))
{
_helper.AddAuthCookies(OperationContext.Current);
UserProfile.PropertyData[] data = userProfile.GetUserProfileByName(userName);
return Guid.Parse(GetPropertyValue(data, “UserProfile_GUID”));
}
Or automatically do the same by adding the WCF client side behaviour like this:
<!--use behaviour to implement authentication-->
<behaviors>
<endpointBehaviors>
<behavior name="CookieBehavior">
<CookieBehaviorExtension/>
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="CookieBehaviorExtension" type="ClaimsHelper.CookieBehaviourExtension, ClaimsHelper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
<client>
<endpoint behaviorConfiguration="CookieBehavior" binding="basicHttpBinding" bindingConfiguration="BasicBinding"
contract="UserProfile.UserProfileServiceSoap" name="UserProfileServiceSoap" />
</client>
Which enables you to use a standard web service client call knowing that the authentication conversation is happening under the hood by the WCF client side behaviour.
UserProfile.UserProfileServiceSoapClient userProfile
= new UserProfile.UserProfileServiceSoapClient("UserProfileServiceSoap", _hostUri + "_vti_bin/userprofileservice.asmx");
UserProfile.PropertyData[] data = userProfile.GetUserProfileByName(userName);
return Guid.Parse(GetPropertyValue(data, "UserProfile_GUID"));
Check out the code [office src=”https://skydrive.live.com/embed?cid=E7F2E3C8DA56735E&resid=E7F2E3C8DA56735E%213784&authkey=AAtWCyefTsWHERc” width=”98″ height=”120″]
We will use this library and build on this functionality in later blogs that address some other issues when moving to SharePoint Online.
One most good point of WCF Service Application approach is it provides clear separation and methodological approach to organize source code in specific code library. There are several different ways to create IIS hosted WCF Services using several Visual Studio templates.
One of the reasons I like WCF Service Application strategy is it provides clear separating and methodological strategy to arrange source rule in specific rule collection.
The code sample doesn’t seem to be accessible anymore, and I don’t see it mentioned anywhere else on the internet. Would it be possible to re-upload it?
Hmm yes you are right
It looks like the way to share publically in SkyDrive has changed
Try again now
This blog explain about the problem of movie SharePoint to SharePoint online service which surely and also given technical code about this development.
I would like to see the code example, but don’t a link to anything. Is it still available? Great article.
Thanks!
Michael
Hi I tried to use your code but the name space UserProfileServiceSoapClient cannot be found. has this been deprecated ?
Hi I tried to use the attached code but the UserProfileServiceSoapClient cannot be found. has this been deprecated ?
One of our tech guys has solved an issued by going through your article. Thanks for your help