2

I have an app which authenticates users against Azure AD as so:

Startup.cs

using Microsoft.AspNetCore.Authentication.Cookies;

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddAuthentication(
        SharedOptions => SharedOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme);

    services.AddAuthorization(options =>
    {
        //Auth Policies using group claims
    });
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    //loggerFactory

    app.UseCookieAuthentication();

    app.UseOpenIdConnectAtuhentication(new OpenIdConnectOptions
    {
        ClientID = Configuration["Authentication:AzureAd:ClientId"],
        Authority = Configuration["Authentication:AzureAd:AADInstance"] + Configuration["Authentication:AzureAd:TenantId"],
        CallbackPath = Configuration["Authentication:AzureAd:CallbackPath"]
    });

    //Mvc Routing
}

AccountController.cs

 [HttpGet]
 public IActionResult SignIn()
 {
     return Challenge(
         new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectDefaults.AuthenticationScheme);
 }

On controllers I want to protect I then use [Authorize(Policy = "Whatever")]

All of that is working great, so my question is does the cookie I already have contain the token I need, and if so, do I simply access it with something like User.Claims or do I need the IAuthenticationProvider set up the way it was in the example for .net 4.6 Here.

And if it's the latter how do I do so without using Owin as they have?

I should add that while Authorization is working fine, what I'd like to do now involves things like listing all users in an OU. For which, from what I can tell I'd have to access Microsoft Graph. Perhaps, I'm going in the complete wrong direction?

Christian Neverdal
  • 5,655
  • 6
  • 38
  • 93
  • Related: https://stackoverflow.com/questions/41519132/how-to-store-the-token-received-in-acquiretokenasync-with-active-directory – Ben Cottrell Aug 07 '17 at 10:02

1 Answers1

3

You can get the access token using ADAL. You can find a pretty good example app here: https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect-aspnetcore.

Here is the especially important part where the token is retrieved: https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect-aspnetcore/blob/master/WebApp-WebAPI-OpenIdConnect-DotNet/Startup.cs#L100.

    private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
    {
        // Acquire a Token for the Graph API and cache it using ADAL.  In the TodoListController, we'll use the cache to acquire a token to the Todo List API
        string userObjectId = (context.Ticket.Principal.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value;
        ClientCredential clientCred = new ClientCredential(ClientId, ClientSecret);
        AuthenticationContext authContext = new AuthenticationContext(Authority, new NaiveSessionCache(userObjectId, context.HttpContext.Session));
        AuthenticationResult authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
            context.ProtocolMessage.Code, new Uri(context.Properties.Items[OpenIdConnectDefaults.RedirectUriForCodePropertiesKey]), clientCred, GraphResourceId);

        // Notify the OIDC middleware that we already took care of code redemption.
        context.HandleCodeRedemption();
    }

You get an authorization code from Azure AD, which you need to exchange to an access token or tokens for APIs you want to call. In the case of Microsoft Graph, make sure to set the resource URI to https://graph.microsoft.com (the sample targets Azure AD Graph API).

You can then call the API as shown here: https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect-aspnetcore/blob/master/WebApp-WebAPI-OpenIdConnect-DotNet/Controllers/TodoController.cs#L31

            string userObjectID = (User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value;
            AuthenticationContext authContext = new AuthenticationContext(Startup.Authority, new NaiveSessionCache(userObjectID, HttpContext.Session));
            ClientCredential credential = new ClientCredential(Startup.ClientId, Startup.ClientSecret);
            result = await authContext.AcquireTokenSilentAsync(Startup.TodoListResourceId, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));

result contains the access token that you need to attach to the HTTP request. It will be retrieved silently from session cache.

I would like to note that this whole process is a lot easier in ASP.NET Core 2.0. The Open Id Connect authentication handler there can actually retrieve the tokens for you.

juunas
  • 54,244
  • 13
  • 113
  • 149