Balaraju Polaki
Balaraju Polaki

Reputation: 133

Getting 401 (Unauthorized) error in Active Directory user image in Multi tenant Application

I have implemented Multi tenant application using Azure Active Directory in Angular 4.After user logged into my application i'm able get user info.But user photo is not getting from the Active directory for that i have implemented Graph API like below snippet.

public Task<UserDto> getPhoto(TenantDto tenantDto)
    {
        var client = new HttpClient();
        client.BaseAddress = new Uri(String.Format("https://graph.windows.net/{0}/users/{1}/thumbnailPhoto?api-version=1.6", tenantDto.tenantKey, tenantDto.email));
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("image/jpeg"));
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tenantDto.token);
        HttpResponseMessage response = client.GetAsync("").Result;
        if (response.IsSuccessStatusCode)
        {
            return null;
            //Status status = response.Content.ReadAsAsync<Status>().Result;
            //if (status.Code == 200)
            //    InBoundResponse = JsonConvert.DeserializeObject<InBoundCallResponse>(status.Data.ToString());
            //return InBoundResponse;
        }
        else
        {
            return null;
        }
    }

Here tenantDto.token is nothing but a logged in user "token" While calling this Graph API i'm getting 401 (Unauthorized) error. I have tried all but no use. I have changed Graph API setting s in Active Directory APP also like below attachment enter image description here

Also i have tried like below code it's working only for single tenant

    [Route("AdUserImage"), HttpGet]
    public async Task<HttpResponseMessage> userImage()
    {
        var authContext = new AuthenticationContext("https://login.windows.net/sampletest.onmicrosoft.com/oauth2/token");
        var credential = new ClientCredential(clientID, clientSecret);
        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 == "[email protected]").ExecuteSingleAsync();
        DataServiceStreamResponse photo = await user.ThumbnailPhoto.DownloadAsync();
        using (MemoryStream s = new MemoryStream())
        {
            photo.Stream.CopyTo(s);
            var encodedImage = Convert.ToBase64String(s.ToArray());
        }
        //string token = await HttpAppAuthenticationAsync();
        Status status = new Status("OK");
        status = new Status("Found", null, "User exists.");

        return Request.CreateResponse(HttpStatusCode.OK, status, _jsonMediaTypeFormatter);
    }

but i need to implement for Multi tenant app.

Any Answer Appreciated.

Thanks in Advance........!

Upvotes: 1

Views: 1402

Answers (2)

Balaraju Polaki
Balaraju Polaki

Reputation: 133

I'm using Delegate-user token as per your explnation using below url https://login.microsoftonline.com/{tenant}/oauth2/authorize?response_type=token&client_id={clientId}&redirect_uri={redirect_uri}&resource=https%3A%2F%2Fgraph.windows.net&nonce={nonce}

But still not able receiving but i'm able getting 200 status but token is not return.i have implemented like below

                var client = new HttpClient();
            client.BaseAddress = new Uri("https://login.microsoftonline.com/{TenantID}/oauth2/authorize?response_type=token&client_id={ClientID}&redirect_uri={ApplicationUrl}&resource=https%3A%2F%2Fgraph.windows.net&nonce=a9d7730c-79f3-4092-803a-07f346de2cdf");
            client.DefaultRequestHeaders.Accept.Clear();

            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html"));

            HttpResponseMessage response = client.GetAsync("").Result;
            if (response.IsSuccessStatusCode)
            {

            }
            else
            {
                //return null;
            }

It's not return the token.it is returning html content in success block

Upvotes: 0

Fei Xue
Fei Xue

Reputation: 14649

Delegate-user token:

1 .Acquire the token via the implict flow:

https://login.microsoftonline.com/{tenant}/oauth2/authorize?response_type=token&client_id={clientId}&redirect_uri={redirect_uri}&resource=https%3A%2F%2Fgraph.windows.net&nonce={nonce}

2 .Call the Azure AD Graph

GET: https://graph.windows.net/{tenant}/me/thumbnailPhoto?api-version=1.6
Content-Type: image/jpeg

Application token:

1 .Acquire the token via the client credentials flow

POST:https://login.microsoftonline.com/{tenant}/oauth2/token
grant_type=client_credentials&client_id={client_id}&client_secret={client_secret}&resource=https%3A%2F%2Fgraph.windows.net

2 .Call the Azure AD Graph

GET:https://graph.windows.net/{tenant}/users/{upn}/thumbnailPhoto?api-version=1.6
Content-Type: image/jpeg

If you only to get the thumbnail photo of sign-in user for the multiple tenant, you should login-in with Azure AD first and acquire the access token for the delegate user and used that token to call Azure AD Graph REST. Difference between these two kinds of token, you can refer the links below:

Get access on behalf of a user

Get access without a user

Upvotes: 1

Related Questions