12

We have set the Azure AD as a identity provider in our application. We want to display profile picture that should come from Azure AD, in the application.

In order to test, I have added one Windows Live Id account (which has a profile picture) in the Azure AD. We then tried it using Graph Explorer, but no luck.

How do we get the profile picture from Azure AD?

Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
Hitesh
  • 1,067
  • 1
  • 10
  • 27

3 Answers3

10

You can use Azure Active Directory Graph Client to get user thumbnail photo

var servicePoint = new Uri("https://graph.windows.net");
// e.g. xxx.onmicrosoft.com
var serviceRoot = new Uri(servicePoint, "<your tenant>"); 

// ClientID and SecretKey are defined when you register application
// with Azure AD
const string clientId  = "<clientId>";
const string secretKey = "<secretKey>";

var authContext = new AuthenticationContext("https://login.windows.net/<tenant>/oauth2/token");
var credential  = new ClientCredential(clientId, secretKey);

ActiveDirectoryClient directoryClient = new ActiveDirectoryClient(serviceRoot, async () => {
    var result = await authContext.AcquireTokenAsync("https://graph.windows.net/", credential);
    return result.AccessToken;
});

var user = await directoryClient.Users
    .Where(x => x.UserPrincipalName == "<username>")
    .ExecuteSingleAsync();

DataServiceStreamResponse photo = await user.ThumbnailPhoto.DownloadAsync();

using (MemoryStream s = new MemoryStream()){
    photo.Stream.CopyTo(s);
    var encodedImage = Convert.ToBase64String(s.ToArray());
}

Azure AD returns user's photo in binary format, you need to convert to Base64 string

GROVER.
  • 4,071
  • 2
  • 19
  • 66
Hanh Nguyen
  • 101
  • 1
  • 3
3

Getting photos through Graph Explorer is not supported. Assuming that "signedInUser" already contains the signed in user entity, then this code snippet using the client library should work for you...

        #region get signed in user's photo
        if (signedInUser.ObjectId != null)
        {
            IUser sUser = (IUser)signedInUser;
            IStreamFetcher photo = (IStreamFetcher)sUser.ThumbnailPhoto;
            try
            {
                DataServiceStreamResponse response =
                photo.DownloadAsync().Result;
                Console.WriteLine("\nUser {0} GOT thumbnailphoto", signedInUser.DisplayName);
            }
            catch (Exception e)
            {
                Console.WriteLine("\nError getting the user's photo - may not exist {0} {1}", e.Message,
                    e.InnerException != null ? e.InnerException.Message : "");
            }
        }
        #endregion

Alternatively you can do this through REST and it should look like this: GET https://graph.windows.net/myorganization/users//thumbnailPhoto?api-version=1.5 Hope this helps,

Dan Kershaw - MSFT
  • 5,833
  • 1
  • 14
  • 23
  • 1
    Thanks Dan. Just one silly question, where do I get signedInUser entity from? – Hitesh Apr 28 '15 at 08:49
  • full explanation: https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/profilephoto_get – Black Sep 24 '18 at 07:03
2

According to the Azure AD Graph API Docs, Microsoft recommends transitioning to Microsoft Graph, as the Azure AD Graph API is being phased out.

However, to easily grab the photo via Azure AD, for now, use this URL template:

https://graph.windows.net/myorganization/users/{user_id}/thumbnailPhoto?api-version={version}

For example (this is a fake user id):

https://graph.windows.net/myorganization/users/abc1d234-01ab-1a23-12ab-abc0d123e456/thumbnailPhoto?api-version=1.6

The code below assumes you already have an authenticated user, with a token. This is a simplistic example; you'll want to change the return value to suit your needs, add error checking, etc.

const string ThumbUrl = "https://graph.windows.net/myorganization/users/{0}/thumbnailPhoto?api-version=1.6";

// Attempts to retrieve the thumbnail image for the specified user, with fallback.
// Returns: Fully formatted string for supplying as the src attribute value of an img tag.
private string GetUserThumbnail(string userId)
{
    string thumbnail = "some base64 encoded fallback image";
    string mediaType = "image/jpg"; // whatever your fallback image type is
    string requestUrl = string.Format(ThumbUrl, userId);

    HttpClient client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", GetToken());
    HttpResponseMessage response = client.GetAsync(requestUrl).Result;

    if (response.IsSuccessStatusCode)
    {
        // Read the response as a byte array
        var responseBody = response.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult();

        // The headers will contain information on the image type returned
        mediaType = response.Content.Headers.ContentType.MediaType;

        // Encode the image string
        thumbnail = Convert.ToBase64String(responseBody);
    }

    return $"data&colon;{mediaType};base64,{thumbnail}";
}

// Factored out for use with other calls which may need the token
private string GetToken()
{
    return HttpContext.Current.Session["Token"] == null ? string.Empty : HttpContext.Current.Session["Token"].ToString();
}
Will
  • 425
  • 4
  • 8