Here is a solution for a particular problem trying to access O365 user profiles without specifying credentials which proper privileges to the user profiles. Notice that it is not enough to add permissions to your app which uses CSOM. Believe me I tried all I could think of.
With the help of a colleague of mine I got a tip to try to explicitly specify credentials. After a few tinkering and wonderin this worked. So the error message which you might get would look
User ‘some user guid data’ doesn’t exist in UPA by UPN or SID, and user with this SID was not found in AD.
Below is a code sample which retrieved encrypted credentials and passes them on the the CSOM client context. After that the code tries to get some data from the user profile.
String manager = String.Empty;
SecureString adminPWSecure = new SecureString();
//get the base tenant admin urls
string tenantAdminLoginName = ConfigurationManager.AppSettings["TenantAdminLoginName"];
string tenantAdminPassword = ConfigurationManager.AppSettings["TenantAdminPassword"];
string tenantAdminUrl = ConfigurationManager.AppSettings["SiteCollectionRequests_TenantAdminSite"];
if (String.IsNullOrEmpty(tenantAdminLoginName) && String.IsNullOrEmpty(tenantAdminPassword))
tenantAdminLoginName = EngineCommon.Hide.Decrypt(tenantAdminLoginName);
foreach (char c in EngineCommon.Hide.Decrypt(tenantAdminPassword).ToCharArray()) adminPWSecure.AppendChar(c);
using (ClientContext clientContext = new ClientContext(tenantAdminUrl))
clientContext.Credentials = new SharePointOnlineCredentials(tenantAdminLoginName, adminPWSecure);
// Get the people manager instance for tenant context
PeopleManager peopleManager = new PeopleManager(clientContext);
var managerData = peopleManager.GetUserProfilePropertyFor(userName, "Manager");
if (managerData != null && !String.IsNullOrEmpty(managerData.Value))
PersonProperties personProperties = peopleManager.GetPropertiesFor(managerData.Value);
manager = personProperties.Email;
} catch(Exception ex)
Console.Write("Failed to get a manager info for a user: " + ex.Message + ex.StackTrace);