Skip to content

Commit 7268694

Browse files
authored
Blazor WASM security topic updates (#18356)
1 parent 6015f71 commit 7268694

9 files changed

Lines changed: 215 additions & 114 deletions

aspnetcore/includes/blazor-security/logindisplay-component.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ The `LoginDisplay` component (*Shared/LoginDisplay.razor*) is rendered in the `M
1414
<AuthorizeView>
1515
<Authorized>
1616
Hello, @context.User.Identity.Name!
17-
<button class="nav-link btn btn-link" @onclick="BeginSignOut">
17+
<button class="nav-link btn btn-link" @onclick="BeginLogout">
1818
Log out
1919
</button>
2020
</Authorized>
@@ -24,7 +24,7 @@ The `LoginDisplay` component (*Shared/LoginDisplay.razor*) is rendered in the `M
2424
</AuthorizeView>
2525
2626
@code {
27-
private async Task BeginSignOut(MouseEventArgs args)
27+
private async Task BeginLogout(MouseEventArgs args)
2828
{
2929
await SignOutManager.SetSignOutState();
3030
Navigation.NavigateTo("authentication/logout");

aspnetcore/includes/blazor-security/usermanager-signinmanager.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ Set the user identifier claim type when a Server app requires:
88
In `Startup.ConfigureServices`:
99

1010
```csharp
11+
using System.Security.Claims;
12+
13+
...
14+
1115
services.Configure<IdentityOptions>(options =>
1216
options.ClaimsIdentity.UserIdClaimType = ClaimTypes.NameIdentifier);
1317
```
@@ -33,7 +37,7 @@ namespace {APP NAMESPACE}.Server.Controllers
3337
[Route("[controller]")]
3438
public class WeatherForecastController : ControllerBase
3539
{
36-
private readonly UserManager<ApplicationUser> _userManager;
40+
private readonly UserManager<ApplicationUser> userManager;
3741

3842
private static readonly string[] Summaries = new[]
3943
{
@@ -47,15 +51,15 @@ namespace {APP NAMESPACE}.Server.Controllers
4751
UserManager<ApplicationUser> userManager)
4852
{
4953
this.logger = logger;
50-
_userManager = userManager;
54+
this.userManager = userManager;
5155
}
5256

5357
[HttpGet]
5458
public async Task<IEnumerable<WeatherForecast>> Get()
5559
{
5660
var rng = new Random();
5761

58-
var user = await _userManager.GetUserAsync(User);
62+
var user = await userManager.GetUserAsync(User);
5963

6064
if (user != null)
6165
{

aspnetcore/security/blazor/webassembly/hosted-with-azure-active-directory-b2c.md

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,30 @@ This article describes how to create a Blazor WebAssembly standalone app that us
2323

2424
### Create a tenant
2525

26-
Follow the guidance in [Tutorial: Create an Azure Active Directory B2C tenant](/azure/active-directory-b2c/tutorial-create-tenant) to create an AAD B2C tenant and record the following information:
26+
Follow the guidance in [Tutorial: Create an Azure Active Directory B2C tenant](/azure/active-directory-b2c/tutorial-create-tenant) to create an AAD B2C tenant.
27+
28+
Record the following information:
2729

2830
* AAD B2C instance (for example, `https://contoso.b2clogin.com/`, which includes the trailing slash)
2931
* AAD B2C Tenant domain (for example, `contoso.onmicrosoft.com`)
3032

3133
### Register a server API app
3234

33-
Follow the guidance in [Tutorial: Register an application in Azure Active Directory B2C](/azure/active-directory-b2c/tutorial-register-applications) to register an AAD app for the *Server API app* in the **Azure Active Directory** > **App registrations** area of the Azure portal:
35+
Follow the guidance in [Tutorial: Register an application in Azure Active Directory B2C](/azure/active-directory-b2c/tutorial-register-applications) to register an AAD app for the *Server API app*:
3436

35-
1. Select **New registration**.
37+
1. In **Azure Active Directory** > **App registrations**, select **New registration**.
3638
1. Provide a **Name** for the app (for example, **Blazor Server AAD B2C**).
37-
1. For **Supported account types**, select **Accounts in any organizational directory or any identity provider. For authenticating users with Azure AD B2C.** (multi-tenant) for this experience.
39+
1. For **Supported account types**, select the multi-tenant option: **Accounts in any organizational directory or any identity provider. For authenticating users with Azure AD B2C.**
3840
1. The *Server API app* doesn't require a **Redirect URI** in this scenario, so leave the drop down set to **Web** and don't enter a redirect URI.
3941
1. Confirm that **Permissions** > **Grant admin concent to openid and offline_access permissions** is enabled.
4042
1. Select **Register**.
4143

44+
Record the following information:
45+
46+
* *Server API app* Application ID (Client ID) (for example, `11111111-1111-1111-1111-111111111111`)
47+
* Directory ID (Tenant ID) (for example, `222222222-2222-2222-2222-222222222222`)
48+
* AAD Tenant domain (for example, `contoso.onmicrosoft.com`) &ndash; The domain is available as the **Publisher domain** in the **Branding** blade of the Azure portal for the registered app.
49+
4250
In **Expose an API**:
4351

4452
1. Select **Add a scope**.
@@ -51,23 +59,22 @@ In **Expose an API**:
5159

5260
Record the following information:
5361

54-
* *Server API app* Application ID (Client ID) (for example, `11111111-1111-1111-1111-111111111111`)
5562
* App ID URI (for example, `https://contoso.onmicrosoft.com/11111111-1111-1111-1111-111111111111`, `api://11111111-1111-1111-1111-111111111111`, or the custom value that you provided)
56-
* Directory ID (Tenant ID) (for example, `222222222-2222-2222-2222-222222222222`)
57-
* *Server API app* App ID URI (for example, `https://contoso.onmicrosoft.com/11111111-1111-1111-1111-111111111111`, the Azure portal might default the value to the Client ID)
5863
* Default scope (for example, `API.Access`)
5964

6065
### Register a client app
6166

62-
Follow the guidance in [Tutorial: Register an application in Azure Active Directory B2C](/azure/active-directory-b2c/tutorial-register-applications) again to register an AAD app for the *Client app* in the **Azure Active Directory** > **App registrations** area of the Azure portal:
67+
Follow the guidance in [Tutorial: Register an application in Azure Active Directory B2C](/azure/active-directory-b2c/tutorial-register-applications) again to register an AAD app for the *Client app*:
6368

64-
1. Select **New registration**.
69+
1. In **Azure Active Directory** > **App registrations**, select **New registration**.
6570
1. Provide a **Name** for the app (for example, **Blazor Client AAD B2C**).
66-
1. For **Supported account types**, select **Accounts in any organizational directory or any identity provider. For authenticating users with Azure AD B2C.** (multi-tenant) for this experience.
67-
1. Leave the **Redirect URI** drop down set to **Web**, and provide a redirect URI of `https://localhost:5001/authentication/login-callback`.
71+
1. For **Supported account types**, select the multi-tenant option: **Accounts in any organizational directory or any identity provider. For authenticating users with Azure AD B2C.**
72+
1. Leave the **Redirect URI** drop down set to **Web**, and provide the following redirect URI: `https://localhost:5001/authentication/login-callback`
6873
1. Confirm that **Permissions** > **Grant admin concent to openid and offline_access permissions** is enabled.
6974
1. Select **Register**.
7075

76+
Record the Application ID (Client ID) (for example, `11111111-1111-1111-1111-111111111111`).
77+
7178
In **Authentication** > **Platform configurations** > **Web**:
7279

7380
1. Confirm the **Redirect URI** of `https://localhost:5001/authentication/login-callback` is present.
@@ -77,37 +84,37 @@ In **Authentication** > **Platform configurations** > **Web**:
7784

7885
In **API permissions**:
7986

80-
1. Confirm that the app has **Microsoft Graph** > **User.Read** permission.
8187
1. Select **Add a permission** followed by **My APIs**.
8288
1. Select the *Server API app* from the **Name** column (for example, **Blazor Server AAD B2C**).
8389
1. Open the **API** list.
8490
1. Enable access to the API (for example, `API.Access`).
8591
1. Select **Add permissions**.
8692
1. Select the **Grant admin content for {TENANT NAME}** button. Select **Yes** to confirm.
8793

94+
Record the App ID URI (for example, `https://{ORGANIZATION}.onmicrosoft.com/{SERVER API APP CLIENT ID OR CUSTOM VALUE}`).
95+
8896
In **Home** > **Azure AD B2C** > **User flows**:
8997

9098
[Create a sign-up and sign-in user flow](/azure/active-directory-b2c/tutorial-create-user-flows)
9199

92100
At a minimum, select the **Application claims** > **Display Name** user attribute to populate the `context.User.Identity.Name` in the `LoginDisplay` component (*Shared/LoginDisplay.razor*).
93101

94-
Record the following information:
95-
96-
* Record the *Client app* Application ID (Client ID) (for example, `33333333-3333-3333-3333-333333333333`).
97-
* Record the sign-up and sign-in user flow name created for the app (for example, `B2C_1_signupsignin`).
102+
Record the sign-up and sign-in user flow name created for the app (for example, `B2C_1_signupsignin`).
98103

99104
### Create the app
100105

101106
Replace the placeholders in the following command with the information recorded earlier and execute the command in a command shell:
102107

103108
```dotnetcli
104-
dotnet new blazorwasm -au IndividualB2C --aad-b2c-instance "{AAD B2C INSTANCE}" --api-client-id "{SERVER API APP CLIENT ID}" --app-id-uri "{SERVER API APP ID URI}" --client-id "{CLIENT APP CLIENT ID}" --default-scope "{DEFAULT SCOPE}" --domain "{DOMAIN}" -ho -ssp "{SIGN UP OR SIGN IN POLICY}" --tenant-id "{TENANT ID}"
109+
dotnet new blazorwasm -au IndividualB2C --aad-b2c-instance "{AAD B2C INSTANCE}" --api-client-id "{SERVER API APP CLIENT ID}" --app-id-uri "{SERVER API APP ID URI}" --client-id "{CLIENT APP CLIENT ID}" --default-scope "{DEFAULT SCOPE}" --domain "{TENANT DOMAIN}" -ho -ssp "{SIGN UP OR SIGN IN POLICY}" --tenant-id "{TENANT ID}"
105110
```
106111

107112
To specify the output location, which creates a project folder if it doesn't exist, include the output option in the command with a path (for example, `-o BlazorSample`). The folder name also becomes part of the project's name.
108113

109114
> [!NOTE]
110115
> Pass the App ID URI to the `app-id-uri` option, but note a configuration change might be required in the client app, which is described in the [Access token scopes](#access-token-scopes) section.
116+
>
117+
> Additionally, the scope set up by the Hosted Blazor template might have the App ID URI host repeated. Confirm that the scope configured for the `DefaultAccessTokenScopes` collection is correct in `Program.Main` (*Program.cs*) of the *Client app*.
111118
112119
## Server app configuration
113120

@@ -148,6 +155,10 @@ By default, the `User.Identity.Name` isn't populated.
148155
To configure the app to receive the value from the `name` claim type, configure the [TokenValidationParameters.NameClaimType](xref:Microsoft.IdentityModel.Tokens.TokenValidationParameters.NameClaimType) of the <xref:Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions> in `Startup.ConfigureServices`:
149156

150157
```csharp
158+
using Microsoft.AspNetCore.Authentication.JwtBearer;
159+
160+
...
161+
151162
services.Configure<JwtBearerOptions>(
152163
AzureADB2CDefaults.JwtBearerAuthenticationScheme, options =>
153164
{
@@ -162,9 +173,9 @@ The *appsettings.json* file contains the options to configure the JWT bearer han
162173
```json
163174
{
164175
"AzureAdB2C": {
165-
"Instance": "https://{ORGANIZATION}.b2clogin.com/",
176+
"Instance": "https://{TENANT}.b2clogin.com/",
166177
"ClientId": "{SERVER API APP CLIENT ID}",
167-
"Domain": "{DOMAIN}",
178+
"Domain": "{TENANT DOMAIN}",
168179
"SignUpSignInPolicyId": "{SIGN UP OR SIGN IN POLICY}"
169180
}
170181
}
@@ -231,14 +242,14 @@ Support for `HttpClient` instances is added that include access tokens when maki
231242

232243
```csharp
233244
builder.Services.AddHttpClient("{APP ASSEMBLY}.ServerAPI", client =>
234-
client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
245+
client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
235246
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
236247

237248
builder.Services.AddTransient(sp => sp.GetRequiredService<IHttpClientFactory>()
238249
.CreateClient("{APP ASSEMBLY}.ServerAPI"));
239250
```
240251

241-
Support for authenticating users is registered in the service container with the `AddMsalAuthentication` extension method provided by the `Microsoft.Authentication.WebAssembly.Msal` package. This method sets up all of the services required for the app to interact with the Identity Provider (IP).
252+
Support for authenticating users is registered in the service container with the `AddMsalAuthentication` 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).
242253

243254
*Program.cs*:
244255

@@ -257,7 +268,7 @@ Configuration is supplied by the *wwwroot/appsettings.json* file:
257268
```json
258269
{
259270
"AzureAdB2C": {
260-
"Authority": "{AAD B2C INSTANCE}{DOMAIN}/{SIGN UP OR SIGN IN POLICY}",
271+
"Authority": "{AAD B2C INSTANCE}{TENANT DOMAIN}/{SIGN UP OR SIGN IN POLICY}",
261272
"ClientId": "{CLIENT APP CLIENT ID}",
262273
"ValidateAuthority": false
263274
}
@@ -342,7 +353,10 @@ For more information, see the following sections of the *Additional scenarios* a
342353
343354
## Run the app
344355
345-
Run the app from the Server project. When using Visual Studio, select the Server project in **Solution Explorer** and select the **Run** button in the toolbar or start the app from the **Debug** menu.
356+
Run the app from the Server project. When using Visual Studio, either:
357+
358+
* Set the **Startup Projects** drop down list in the toolbar to the *Server API app* and select the **Run** button.
359+
* Select the Server project in **Solution Explorer** and select the **Run** button in the toolbar or start the app from the **Debug** menu.
346360
347361
<!-- HOLD
348362
[!INCLUDE[](~/includes/blazor-security/usermanager-signinmanager.md)]

0 commit comments

Comments
 (0)