Alexander Schmidt
Alexander Schmidt

Reputation: 5733

Accessing Microsoft Graph with AAD App

I begin with my question. How do I read data from my AAD using Microsoft Graph using an app registration perfomed inside of an Azure AD? Now the details...

I have created an app registration in my Azure Active Directory and allowed access to Microsoft Graph there:

AAD portal with required permissions

To be exact the app has the following permissions:

I use the following code in my ASP.NET MVC app to authenticate my website against the AAD:

public void SignIn()
{
    if (!Request.IsAuthenticated)
    {
        HttpContext.GetOwinContext().Authentication.Challenge(
            new AuthenticationProperties
            {
                RedirectUri = "/"
            },
            OpenIdConnectAuthenticationDefaults.AuthenticationType);
    }
}

which is pretty much the default setting for doing organizational auth. This works and I even can read out my users informations from the AAD profile:

private string GetUserName()
{                        
    var claimsPrincipal = ClaimsPrincipal.Current;           
    var firstName = claimsPrincipal.FindFirst(ClaimTypes.GivenName).Value;
    var lastName = claimsPrincipal.FindFirst(ClaimTypes.Surname).Value;
    return $"{firstName} {lastName}";
}

Now I try to use Microsoft Graph to optain lets say the avatar image. There are some official MS samples available here. But all of them rely on a NuGet package called Microsoft.Identity.Client which is preview currently. The other thing is that MS wants me to register my app under Application Registration Portal which makes no sense to me because I already have an registered app.

I already tries to retrieve my bearer token from my claims identity and use it in Graph like this:

var ci = (System.Security.Claims.ClaimsIdentity)ClaimsPrincipal.Current.Identity;
var token = ((System.IdentityModel.Tokens.BootstrapContext)ci.BootstrapContext).Token;
var endpoint = "https://graph.microsoft.com/v1.0/me/photo/$value";
using (var client = new HttpClient())
{
    using (var request = new HttpRequestMessage(HttpMethod.Get, endpoint))
    {                    
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
        var response = await client.SendAsync(request);                 
        if (response.IsSuccessStatusCode)
        {
            return await response.Content.ReadAsStreamAsync();
        }                    
    }
}
return null;

But this gives my 401.

Upvotes: 2

Views: 1659

Answers (1)

juunas
juunas

Reputation: 58873

You need to get a token with ADAL using your app's client id and secret.

You can get ADAL from NuGet: https://www.nuget.org/packages/Microsoft.IdentityModel.Clients.ActiveDirectory/

E.g.:

string authority = "https://login.microsoftonline.com/your-tenant-id";
var authenticationContext = new AuthenticationContext(authority);

string clientId = "your-app-client-id";
string clientSecret = "yourappclientsecret";
var clientCredential = new ClientCredential(clientId, clientSecret);

string resource = "https://graph.microsoft.com";
AuthenticationResult authenticationResult = await authenticationContext.AcquireTokenAsync(resource, clientCredential);

string accessToken = authenticationResult.AccessToken;

Replace your-tenant-id with your Azure AD tenant id or domain name (e.g. mytenant.onmicrosoft.com). Replace your-app-client-id with the client id/application id of the app registered in AAD. Replace yourappclientsecret with the client secret/key created for the app in AAD.

I have hard-coded them in the example to make it easier to follow. In production you should not be storing credentials in code.

Upvotes: 3

Related Questions