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|[email protected]"; 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|[email protected]"; 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?