1

I have a console application where I am updating SharePoint Online user profile properties via CSOM. When I do it via the following code below (using a username and password), it works just fine.

private static void UpdateUserProfileProperties()
{
    var userAccountName = "i:0#.f|membership|myAccounName@mySite.com";
    var siteUrl = "https://mySite-admin.sharepoint.com";
    var myUserName = "myUserName";
    var myPassword = "myPassword";
    var secureStringPassword = new SecureString();
    myPassword.ToList().ForEach(c => secureStringPassword.AppendChar(c));

    using (var context = new ClientContext(siteUrl))
    {
        var credentials = new SharePointOnlineCredentials(myUserName, secureStringPassword);
        context.Credentials = credentials;

        var peopleManager = new PeopleManager(context);
        var personProperties = peopleManager.GetPropertiesFor(userAccountName);

        context.Load(personProperties, p => p.AccountName, p => p.UserProfileProperties);
        context.ExecuteQuery();
    }
}

Now, I have created an app in SharePoint (via the AppRegNew.aspx page). I granted the app tenant-level permissions (via the AppInv.aspx page) and the following Permission Request XML:

<AppPermissionRequests AllowAppOnlyPolicy="true">
    <AppPermissionRequest Scope="http://sharepoint/content/tenant" Right="FullControl"/>
</AppPermissionRequests>

Now, I am using the clientID/clientSecret to authenticate instead of a username and password - using this code:

public static void UpdateUserProfileProperties2()
{
    var userAccountName = "i:0#.f|membership|myAccounName@mySite.com";
    var siteUrl = "https://mySite-admin.sharepoint.com";
    var siteUri = new Uri(siteUrl);
    var siteRealm = TokenHelper.GetRealmFromTargetUrl(siteUri);
    var siteToken = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, siteUri.Authority, siteRealm).AccessToken;

    using (var context = TokenHelper.GetClientContextWithAccessToken(siteUri.ToString(), siteToken))
    {
        var peopleManager = new PeopleManager(context);
        var personProperties = peopleManager.GetPropertiesFor(userAccountName);

        context.Load(personProperties, p => p.AccountName, p => p.UserProfileProperties);
        context.ExecuteQuery();
    }
}

I can get the token and the context just fine. When the line context.ExecuteQuery(); executes, I get the following exception:

Microsoft.SharePoint.Client.ServerUnauthorizedAccessException: Access denied. You do not have permission to perform this action or access this resource.

The app clientID/clientSecret works for all sorts of other site-based operations. Is it possible to load the user properties in the admin site via a clientID/clientSecret? If so, can you provide an example? How can I grant the app the appropriate permissions?

3

That code will only run with credentials provided for a tenant administrator. It will not work against App-only policy.

There is a User Profiles scope in the app permissions manifest, but, like the Taxonomy permission scope, it does not seem to actually do anything (in an Office 365 context, anyway).

http://www.vrdmn.com/2014/11/set-another-users-profile-properties.html (see point number 2)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.