Skip to content

Latest commit

 

History

History
220 lines (149 loc) · 11.4 KB

File metadata and controls

220 lines (149 loc) · 11.4 KB
title Secure an ASP.NET Core Blazor WebAssembly standalone app with Microsoft Entra ID
author guardrex
description Learn how to secure an ASP.NET Core Blazor WebAssembly standalone app with Microsoft Entra ID.
monikerRange >= aspnetcore-3.1
ms.author wpickett
ms.custom devx-track-csharp, mvc, sfi-ropc-nochange
ms.date 11/11/2025
uid blazor/security/webassembly/standalone-with-microsoft-entra-id

Secure an ASP.NET Core Blazor WebAssembly standalone app with Microsoft Entra ID

[!INCLUDE]

This article explains how to create a standalone Blazor WebAssembly app that uses Microsoft Entra ID (ME-ID) for authentication.

For additional security scenario coverage after reading this article, see xref:blazor/security/webassembly/additional-scenarios.

Walkthrough

The subsections of the walkthrough explain how to:

  • Create a tenant in Azure
  • Register an app in Azure
  • Create the Blazor app
  • Run the app

Create a tenant in Azure

Follow the guidance in Quickstart: Set up a tenant to create a tenant in ME-ID.

Register an app in Azure

Register an ME-ID app:

  1. Navigate to Microsoft Entra ID in the Azure portal. Select Applications > App registrations in the sidebar. Select the New registration button.
  2. Provide a Name for the app (for example, Blazor Standalone ME-ID).
  3. Choose a Supported account types. You may select Accounts in this organizational directory only for this experience.
  4. Set the Redirect URI dropdown list to Single-page application (SPA) and provide the following redirect URI: https://localhost/authentication/login-callback. If you know the production redirect URI for the Azure default host (for example, azurewebsites.net) or the custom domain host (for example, contoso.com), you can also add the production redirect URI at the same time that you're providing the localhost redirect URI. Be sure to include the port number for non-:443 ports in any production redirect URIs that you add.
  5. If you're using an unverified publisher domain, clear the Permissions > Grant admin consent to openid and offline_access permissions checkbox. If the publisher domain is verified, this checkbox isn't present.
  6. Select Register.

Note

Supplying the port number for a localhost ME-ID redirect URI isn't required. For more information, see Redirect URI (reply URL) restrictions and limitations: Localhost exceptions (Entra documentation).

Record the following information:

  • Application (client) ID (for example, 00001111-aaaa-2222-bbbb-3333cccc4444)
  • Directory (tenant) ID (for example, aaaabbbb-0000-cccc-1111-dddd2222eeee)

In Authentication > Platform configurations > Single-page application:

  1. Confirm the redirect URI of https://localhost/authentication/login-callback is present.
  2. In the Implicit grant section, ensure that the checkboxes for Access tokens and ID tokens aren't selected. Implicit grant isn't recommended for Blazor apps using MSAL v2.0 or later. For more information, see xref:blazor/security/webassembly/index#use-the-authorization-code-flow-with-pkce.
  3. The remaining defaults for the app are acceptable for this experience.
  4. Select the Save button if you made changes.

Create the Blazor app

Create the app in an empty folder. Replace the placeholders in the following command with the information recorded earlier and execute the command in a command shell:

dotnet new blazorwasm -au SingleOrg --client-id "{CLIENT ID}" -o {PROJECT NAME} --tenant-id "{TENANT ID}"
Placeholder Azure portal name Example
{PROJECT NAME} BlazorSample
{CLIENT ID} Application (client) ID 00001111-aaaa-2222-bbbb-3333cccc4444
{TENANT ID} Directory (tenant) ID aaaabbbb-0000-cccc-1111-dddd2222eeee

The output location specified with the -o|--output option creates a project folder if it doesn't exist and becomes part of the project's name.

[!INCLUDE]

Run the app

Use one of the following approaches to run the app:

  • Visual Studio
    • Select the Run button.
    • Use Debug > Start Debugging from the menu.
    • Press F5.
  • .NET CLI command shell: Execute the dotnet watch (or dotnet run) command from the app's folder.

Remote authentication paths

[!INCLUDE]

Parts of the app

This section describes the parts of an app generated from the Blazor WebAssembly project template and how the app is configured. There's no specific guidance to follow in this section for a basic working application if you created the app using the guidance in the Walkthrough section. The guidance in this section is helpful for updating an app to authenticate and authorize users. However, an alternative approach to updating an app is to create a new app from the guidance in the Walkthrough section and moving the app's components, classes, and resources to the new app.

Authentication package

When an app is created to use Work or School Accounts (SingleOrg), the app automatically receives a package reference for the Microsoft Authentication Library (Microsoft.Authentication.WebAssembly.Msal). The package provides a set of primitives that help the app authenticate users and obtain tokens to call protected APIs.

If adding authentication to an app, manually add the Microsoft.Authentication.WebAssembly.Msal package to the app.

[!INCLUDE]

The Microsoft.Authentication.WebAssembly.Msal package transitively adds the Microsoft.AspNetCore.Components.WebAssembly.Authentication package to the app.

Authentication service support

Support for authenticating users is registered in the service container with the xref:Microsoft.Extensions.DependencyInjection.MsalWebAssemblyServiceCollectionExtensions.AddMsalAuthentication%2A extension method provided by the Microsoft.Authentication.WebAssembly.Msal package. This method sets up the services required for the app to interact with the Identity Provider (IP).

In the Program file:

builder.Services.AddMsalAuthentication(options =>
{
    builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
});

The xref:Microsoft.Extensions.DependencyInjection.MsalWebAssemblyServiceCollectionExtensions.AddMsalAuthentication%2A method accepts a callback to configure the parameters required to authenticate an app. The values required for configuring the app can be obtained from the ME-ID configuration when you register the app.

wwwroot/appsettings.json configuration

Configuration is supplied by the wwwroot/appsettings.json file:

{
  "AzureAd": {
    "Authority": "https://login.microsoftonline.com/{TENANT ID}",
    "ClientId": "{CLIENT ID}",
    "ValidateAuthority": true
  }
}

Example:

{
  "AzureAd": {
    "Authority": "https://login.microsoftonline.com/e86c78e2-...-918e0565a45e",
    "ClientId": "00001111-aaaa-2222-bbbb-3333cccc4444",
    "ValidateAuthority": true
  }
}

Access token scopes

The Blazor WebAssembly template doesn't automatically configure the app to request an access token for a secure API. To provision an access token as part of the sign-in flow, add the scope to the default access token scopes of the xref:Microsoft.Authentication.WebAssembly.Msal.Models.MsalProviderOptions:

builder.Services.AddMsalAuthentication(options =>
{
    ...
    options.ProviderOptions.DefaultAccessTokenScopes.Add("{SCOPE URI}");
});

Specify additional scopes with AdditionalScopesToConsent:

options.ProviderOptions.AdditionalScopesToConsent.Add("{ADDITIONAL SCOPE URI}");

Note

xref:Microsoft.Authentication.WebAssembly.Msal.Models.MsalProviderOptions.AdditionalScopesToConsent%2A isn't able to provision delegated user permissions for Microsoft Graph via the Microsoft Entra ID consent UI when a user first uses an app registered in Microsoft Azure. For more information, see xref:blazor/security/webassembly/graph-api?pivots=graph-sdk-5#defaultaccesstokenscopes-versus-additionalscopestoconsent.

For more information, see the following resources:

Login mode

[!INCLUDE]

Imports file

The xref:Microsoft.AspNetCore.Components.Authorization?displayProperty=fullName namespace is made available throughout the app via the _Imports.razor file:

...
@using Microsoft.AspNetCore.Components.Authorization
...

Index page

[!INCLUDE]

App component

[!INCLUDE]

RedirectToLogin component

[!INCLUDE]

LoginDisplay component

[!INCLUDE]

Authentication component

[!INCLUDE]

Troubleshoot

[!INCLUDE]

Additional resources