Saturday, January 11, 2014

Automatically updating User Profile properties in SharePoint Online/Office 365 not working

This might seem a common business scenario – you are using SharePoint Online and you want to automatically import some information from a third party system into the SharePoint Online user profiles. Unfortunately you are out of luck – in most cases – at this moment there is no option available to do this. This blog post explains the different scenarios and what is possible and what is not.

Option 1 – Using the SharePoint Client Side Object Model (CSOM)

As outlined in Work with user profiles in SharePoint 2013 , you have to use the server object model to create or change user profiles because they're read-only from client APIs (except the user profile picture).

Option 2 – Using the SharePoint Server Side Object Model

Not possible for SharePoint Online – you are out of luck here.

Option 3 – Using the (deprecated) SharePoint UserProfileService.asmx web service

For those of you who have been working with SharePoint Server 2007 might remember the UserProfileService.asmx webservice which provides a user profile interface for remote clients to read and create user profiles. This web service is still available in SharePoint Online (although considered deprecated). One thing which is a little trickier though in SharePoint Online is passing the correct credentials to your webservice to authenticate.

Luckily I found this blog post – Connecting to Office 365 using Client Side Object Model and Web Services which helped quite a lot.  To authenticate when connecting to your web service, you need to create an authentication cookie and pass it directly to the web service as well as make sure that login is correctly formatted. The next code snippet shows how to do this

static void AuthenticateUser(string login, string password)
{
//Reference - http://tomaszrabinski.pl/wordpress/2013/03/18/connecting-to-office-365-using-client-side-object-model-and-web-services/
var targetSite = new Uri(siteUrl);
var securePassword = new SecureString();

foreach (char c in password)
{
securePassword.AppendChar(c);
}


var onlineCredentials = new SharePointOnlineCredentials(login, securePassword);

ups = new UserProfileServiceRef.UserProfileService();
ups.UseDefaultCredentials = false;
string authCookieValue = onlineCredentials.GetAuthenticationCookie(targetSite);
ups.CookieContainer = new CookieContainer();
ups.CookieContainer.Add(new Cookie(
"FedAuth",
authCookieValue.TrimStart("SPOIDCRL=".ToCharArray()),// Remove the prefix from the cookie's value
String.Empty, targetSite.Authority));
}



To actually update a user profile property you can use the following code snippet.

static void UpdateProfileProperty(string login, string password, Dictionary<string, string> dictProperties)
{
var claimsLogin = "i:0#.f|membership|" + login;

try
{
//Provide login and password to UPS webservice - there is no global admin user who can
//update profile properties for other users
AuthenticateUser(login, password);

//Update Email
foreach (var pair in dictProperties)
{
UserProfileServiceRef.PropertyData[] newdata = new UserProfileServiceRef.PropertyData[1];
newdata[0] = new UserProfileServiceRef.PropertyData();
newdata[0].Name = pair.Key;
newdata[0].Values = new ValueData[1];
newdata[0].Values[0] = new ValueData();
newdata[0].Values[0].Value = pair.Value;
newdata[0].IsValueChanged = true;
ups.ModifyUserPropertyByAccountName(claimsLogin, newdata);
}
}
catch (Exception ex)
{
//Do something intelligent with your error :-)
}
}



Unfortunately when you try to update the user profile property from another user you will get an “Operation Failure ---] Attempted to perform an unauthorized operation” even when the user is a global administrator on your Office 365 environment.


So for the moment there is no option available for automatic updating SharePoint Online user profile properties from a third party system in a automated fashion without you having the user name and password of every single user.


References:



 


No comments: