microsoftgraph / aspnetcore-connect-sample

[ARCHIVED] This ASP.NET Core MVC sample shows how to connect to Microsoft Graph using delegated permissions and the Azure AD v2.0 (MSAL) endpoint.
MIT License
123 stars 96 forks source link

Code is not usable in a deployed web app. #60

Closed toddheckel closed 4 years ago

toddheckel commented 4 years ago

The approach used in this sample is not feasible in a production environment with a deployed service. The redirect url is formed from a hard-coded base url ("https://localhost") in appsettings.json, which is not practical of course.

According to the MSAL docs the redirect url should be formed by extracting the base url from the http context at the time of the request. It's not clear, however, how to refactor the helper classes from the sample to do this, since ConfigureAzureOptions.Configure(), which is called at startup, uses the Authority string created in the call to ConfidentialClientApplicationBuilder.Create, which if you follow the docs example isn't called until a request, in options.Events.OnAuthorizationCodeReceived.

mark-szabo commented 4 years ago

Thanks @toddheckel! I'll migrate to .NET Core 3.1 and refactor this sample in about two weeks time. Will keep this issue updated! 🙂

toddheckel commented 4 years ago

Thanks Mark. I was able to update the sample to 3.1 myself and I'm happy to contribute if that would be helpful.

toddheckel commented 4 years ago

Also in my service, which I'm updating from Microsoft.AspNetCore.Authentication.MicrosoftAccount, I moved the call to ConfidentialClientApplicationBuilder.Create into the OnAuthorizationCodeReceived callback and set options.Authorization to $"{Instance}/{TenantId}/v2.0/" which seems to work when deployed to Azure.

toddheckel commented 4 years ago

Actually, to get this to work in a multi-tenant setup (supporting work and personal accounts) it was necessary to set the authority to $"{Instance}/common/v2.0/".

mark-szabo commented 4 years ago

Contributions are always welcome! 😉

mark-szabo commented 4 years ago

Hi @toddheckel, finally I had the time for the migration. As far as I see, there are two different things you mentioned: redirect url and authority. Redirect url is the absolute uri on your webapp where the user will get back from AAD after authentication. Authority is the host of the AAD endpoint (most likely login.microsoftonline.com).

Getting the base url of your running app to construct your redirect url is absolutely doable. First add the HttpContextAccessor to the DI container in Startup.cs: services.AddHttpContextAccessor(); Right after you will be able to get the base url in eg. GraphAuthProvider like so:

public GraphAuthProvider(IConfiguration configuration, IHttpContextAccessor httpContext)
{
   // ...

    var baseUrl = $"{httpContext.HttpContext.Request.Scheme}://{httpContext.HttpContext.Request.Host}";

    _app = ConfidentialClientApplicationBuilder.Create(azureOptions.ClientId)
            .WithClientSecret(azureOptions.ClientSecret)
            .WithAuthority(AzureCloudInstance.AzurePublic, AadAuthorityAudience.AzureAdAndPersonalMicrosoftAccount)
            .WithRedirectUri(baseUrl + azureOptions.CallbackPath)
            .Build();

    // ...
}