Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get profile picture from Azure Active Directory

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?

like image 384
Hitesh Avatar asked Apr 27 '15 12:04

Hitesh


3 Answers

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

var servicePoint = new Uri("https://graph.windows.net");
var serviceRoot = new Uri(servicePoint, "<your tenant>"); //e.g. xxx.onmicrosoft.com
const string clientId = "<clientId>";
const string secretKey = "<secretKey>";// ClientID and SecretKey are defined when you register application with Azure AD
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

like image 76
Hanh Nguyen Avatar answered Oct 15 '22 11:10

Hanh Nguyen


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,

like image 23
Dan Kershaw - MSFT Avatar answered Oct 15 '22 12:10

Dan Kershaw - MSFT


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();
}
like image 2
Will Avatar answered Oct 15 '22 13:10

Will