what is the procedure to add Microsoft Identity Platform (Azure AD) authentication to an existing (empty) Blazor project?

Viewed 30

I have looked around for a while and am unable to find any comprehensive reference to list of steps required to integrate Microsoft Identity Platform (Azure AD) authentication into an existing Blazor (or .Net Core Web) app. I have an existing Blazor project which was setup with NO authentication option selected at create time. i am looking to do the following:

  1. authenticate against Azure AD
  2. scaffold/override /MicrosoftIdentity/Account/ actions

appreciate any input that can point me in the right direction.

1 Answers

For #1:

Add to appsettings.json

"Domain": "[Enter the domain of your tenant, e.g. contoso.onmicrosoft.com]",
"ClientId": "Enter_the_Application_Id_here",
"TenantId": "common",

The Microsoft.AspNetCore.Authentication middleware uses a Startup class that's executed when the hosting process starts:

// Get the scopes from the configuration (appsettings.json)
  var initialScopes = Configuration.GetValue<string>("DownstreamApi:Scopes")?.Split(' ');

  public void ConfigureServices(IServiceCollection services)
  {
      // Add sign-in with Microsoft
      services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
        .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))

            // Add the possibility of acquiring a token to call a protected web API
            .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)

                // Enables controllers and pages to get GraphServiceClient by dependency injection
                // And use an in memory token cache
                .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
                .AddInMemoryTokenCaches();

      services.AddControllersWithViews(options =>
      {
          var policy = new AuthorizationPolicyBuilder()
              .RequireAuthenticatedUser()
              .Build();
          options.Filters.Add(new AuthorizeFilter(policy));
      });

      // Enables a UI and controller for sign in and sign out.
      services.AddRazorPages()
          .AddMicrosoftIdentityUI();
  }

The AddAuthentication() method configures the service to add cookie-based authentication. This authentication is used in browser scenarios and to set the challenge to OpenID Connect.

The line that contains .AddMicrosoftIdentityWebApp adds Microsoft identity platform authentication to your application. The application is then configured to sign in users based on the following information in the AzureAD section of the appsettings.json configuration file.

The EnableTokenAcquisitionToCallDownstreamApi method enables your application to acquire a token to call protected web APIs. AddMicrosoftGraph enables your controllers or Razor pages to benefit directly the GraphServiceClient (by dependency injection) and the AddInMemoryTokenCaches methods enables your app to benefit from a token cache.

The Configure() method contains two important methods, app.UseAuthentication() and app.UseAuthorization(), that enable their named functionality. Also in the Configure() method, you must register Microsoft Identity Web routes with at least one call to endpoints.MapControllerRoute() or a call to endpoints.MapControllers():

app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
    endpoints.MapRazorPages();
});

For #2 which implicitly overrides the authorization, protecting a controller for example.

You can protect a controller or its methods by applying the [Authorize] attribute to the controller's class or one or more of its methods. This [Authorize] attribute restricts access by allowing only authenticated users. If the user isn't already authenticated, an authentication challenge can be started to access the controller. In this quickstart, the scopes are read from the configuration file

[AuthorizeForScopes(ScopeKeySection = "DownstreamApi:Scopes")]
public async Task<IActionResult> Index()
{
    var user = await _graphServiceClient.Me.Request().GetAsync();
    ViewData["ApiResult"] = user.DisplayName;

    return View();
}

Source

Related