Leggere il profilo di un utente da uno SharePoint Addin con C# e ASP.NET

In uno SharePoint Addin, realizzato con ASP.NET, può capitare di dover leggere delle proprietà dal Profile Service.
Per leggere le proprietà dell'utente corrente è molto semplice.
Basta istanziare l'oggetto People Manager con il contesto dell'applicazione e leggere le proprietà con il metodo "GetMyProperties()".

            var peopleManager = new PeopleManager(clientContext);
            var personProperties = peopleManager.GetMyProperties();

Se invece dobbiamo leggere il profilo di un altro utente, il lavoro da fare è un po' più complesso e sicuramente non risolvibile con una soluzione "pulitissima".

In questo caso dobbiamo istanziare un nuovo contesto, non per il sito corrente, ma del sito di amministrazione di SharePoint.
Ovviamente questo vi fa capire subito che l'utente che deve avere accesso a quelle informazioni, deve avere accesso anche all'amministrazione del tenant.
Visto che non è il caso di dare a tutti i diritti su quel sito, conviene creare un utente di servizio che ci possa accedere ed usare quello.
Per comodità vi inserisco il codice che sto usando io.
Ovviamente dovete sostituire i valori di esempio che ho messo con i vostri.
Altra nota: il nome dell'utente di cui si vogliono prendere le proprietà deve essere esattamente in quel formato.

        public void ReadUserProfileProperties()
        {
            var serverUrl = "https://tenant-admin.sharepoint.com/";
            var targetUser = "i:0#.f|membership|###email###";

            var adminUsername = "";
            var adminPassword = "";

            var securePassword = new SecureString();
            foreach (char c in adminPassword)
            {
                securePassword.AppendChar(c);
            }

            var clientContext = new ClientContext(serverUrl);
            clientContext.Credentials = new SharePointOnlineCredentials(adminUsername, securePassword);

            var peopleManager = new PeopleManager(clientContext);
            var personProperties = peopleManager.GetPropertiesFor(targetUser);

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

            foreach (var property in personProperties.UserProfileProperties)
            {
                Console.WriteLine(string.Format("Key: {0} - Value: {1}",
                    property.Key.ToString(), property.Value.ToString()));
            }
        }