Skip to content

Commit 8504073

Browse files
authored
Blazor 10.0 updates (#36372)
1 parent 95d4856 commit 8504073

File tree

14 files changed

+30
-77
lines changed

14 files changed

+30
-77
lines changed

aspnetcore/blazor/call-web-api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ Example:
5757

5858
In the app's `Program` file, call:
5959

60-
<!-- UPDATE 10.0 - Missing API doc for 'AddDownstreamApi' -->
60+
<!-- UPDATE 10.0 - Missing API doc for 'Microsoft.Identity.Web.DownstreamApiExtensions.AddDownstreamApi' -->
6161

6262
* <xref:Microsoft.Identity.Web.MicrosoftIdentityWebApiAuthenticationBuilder.EnableTokenAcquisitionToCallDownstreamApi%2A>: Enables token acquisition to call web APIs.
6363
* `AddDownstreamApi`: Microsoft Identity Web packages provide API to create a named downstream web service for making web API calls. <xref:Microsoft.Identity.Abstractions.IDownstreamApi> is injected into a server-side class, which is used to call <xref:Microsoft.Identity.Abstractions.IDownstreamApi.CallApiForUserAsync%2A> to obtain weather data from an external web API (`MinimalApiJwt` project).

aspnetcore/blazor/forms/validation.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1582,9 +1582,6 @@ For model validation defined in a different assembly, such as a library or the `
15821582

15831583
The preceding approach results in validation of the types from both assemblies.
15841584

1585-
<!-- UPDATE 10.0 - MIA API
1586-
`AddValidationForTypesInClient` -->
1587-
15881585
In the following example, the `AddValidationForTypesInClient` method is created for the `.Client` project of a Blazor Web App for validation using types defined in the `.Client` project.
15891586

15901587
`ServiceCollectionExtensions.cs` (in the `.Client` project):

aspnetcore/blazor/fundamentals/environments.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,6 @@ For more information, see the following resources:
219219

220220
### Set the environment for Azure App Service
221221

222-
<!-- UPDATE 10.0 The underlying problem with app settings filename
223-
case sensitivity is tracked for 10.0 by ...
224-
https://github.com/dotnet/aspnetcore/issues/25152 -->
225-
226222
For a standalone Blazor WebAssembly app, you can set the environment manually via [start configuration](#set-the-client-side-environment-via-blazor-startup-configuration) or the [`Blazor-Environment` header](#set-the-client-side-environment-via-header).
227223

228224
For a server-side app, set the environment via an `ASPNETCORE_ENVIRONMENT` app setting in Azure:

aspnetcore/blazor/fundamentals/static-files.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,6 @@ For more information, see <xref:fundamentals/static-files>.
7878

7979
*This section applies to server-side Blazor apps.*
8080

81-
<!-- UPDATE 10.0 Compiler implementation for tilde/slash-based HREFs. -->
82-
8381
Assets are delivered via the <xref:Microsoft.AspNetCore.Components.ComponentBase.Assets?displayProperty=nameWithType> property, which resolves the fingerprinted URL for a given asset. In the following example, Bootstrap, the Blazor project template app stylesheet (`app.css`), and the [CSS isolation stylesheet](xref:blazor/components/css-isolation) (based on an app's namespace of `BlazorSample`) are linked in a root component, typically the `App` component (`Components/App.razor`):
8482

8583
```razor

aspnetcore/blazor/hybrid/tutorials/maui-blazor-web-app.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ Add new project to the solution with the **Blazor Web App** project template. Se
7676
* **Interactivity location**: **Global**
7777
* **Sample pages**: Unselected (disabled)
7878

79-
<!-- UPDATE 10.0 Check on PU issue mentioned below and revise accordingly. -->
79+
<!-- UPDATE 11.0 Check on PU issue mentioned below and revise accordingly. -->
8080

8181
The **Interactivity location** setting to **Global** is important because MAUI apps always run interactively and throw errors on Razor component pages that explicitly specify a render mode. If you don't use a global render mode, you must implement the approach described in the [Use Blazor render modes](#use-blazor-render-modes) section after following the guidance in this section. For more information, see [BlazorWebView needs a way to enable overriding ResolveComponentForRenderMode (`dotnet/aspnetcore` #51235)](https://github.com/dotnet/aspnetcore/issues/51235).
8282

aspnetcore/blazor/includes/prerendering.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
:::moniker range=">= aspnetcore-8.0"
1+
:::moniker range=">= aspnetcore-10.0"
22

33
*This section applies to server-side apps that prerender Razor components. Prerendering is covered in <xref:blazor/components/prerender>.*
44

5-
<!-- UPDATE 10.0 - Persistent component state across enhanced nav
6-
is arriving for RC1.
7-
8-
The following remarks will be updated/versioned
9-
on the upcoming docs RC1 PR.
10-
-->
5+
:::moniker-end
6+
7+
:::moniker range=">= aspnetcore-8.0 < aspnetcore-10.0"
8+
9+
*This section applies to server-side apps that prerender Razor components. Prerendering is covered in <xref:blazor/components/prerender>.*
1110

1211
> [!NOTE]
1312
> Internal navigation for [interactive routing](xref:blazor/fundamentals/routing#static-versus-interactive-routing) in Blazor Web Apps doesn't involve requesting new page content from the server. Therefore, prerendering doesn't occur for internal page requests. If the app adopts interactive routing, perform a full page reload for component examples that demonstrate prerendering behavior. For more information, see <xref:blazor/state-management/prerendered-state-persistence#interactive-routing-and-prerendering>.

aspnetcore/blazor/javascript-interoperability/call-javascript-from-dotnet.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -461,14 +461,12 @@ IJSRuntime JS { get; set; }
461461

462462
:::moniker range=">= aspnetcore-10.0"
463463

464-
<!-- UPDATE 10.0 - MIA API -->
465-
466464
## Create an instance of a JS object using a constructor function
467465

468466
Create an instance of a JS object using a constructor function and get the <xref:Microsoft.JSInterop.IJSObjectReference>/<xref:Microsoft.JSInterop.IJSInProcessObjectReference> .NET handle for referencing the instance with the following API:
469467

470468
* <xref:Microsoft.JSInterop.JSRuntime.InvokeConstructorAsync%2A> (asynchronous)
471-
* `InvokeConstructor` (synchronous)
469+
* <xref:Microsoft.JSInterop.IJSInProcessObjectReference.InvokeConstructor%2A> (synchronous)
472470

473471
Examples in this section demonstrate the API calls with the following `TestClass` with a constructor function (`constructor(text)`):
474472

@@ -498,7 +496,7 @@ An overload is available that takes a <xref:System.Threading.CancellationToken>
498496

499497
### Synchronous `InvokeConstructor`
500498

501-
Use `InvokeConstructor` on <xref:Microsoft.JSInterop.IJSInProcessRuntime> and <xref:Microsoft.JSInterop.IJSInProcessObjectReference> to invoke the specified JS constructor function synchronously. The function is invoked with the `new` operator. In the following example, `TestClass` contains a constructor function, and `classRef` is an <xref:Microsoft.JSInterop.IJSInProcessObjectReference>:
499+
Use <xref:Microsoft.JSInterop.IJSInProcessObjectReference.InvokeConstructor%2A> on <xref:Microsoft.JSInterop.IJSInProcessRuntime> and <xref:Microsoft.JSInterop.IJSInProcessObjectReference> to invoke the specified JS constructor function synchronously. The function is invoked with the `new` operator. In the following example, `TestClass` contains a constructor function, and `classRef` is an <xref:Microsoft.JSInterop.IJSInProcessObjectReference>:
502500

503501
```csharp
504502
var inProcRuntime = ((IJSInProcessRuntime)JSRuntime);
@@ -629,13 +627,12 @@ In server-side scenarios, JS interop calls can't be issued after Blazor's Signal
629627

630628
:::moniker range=">= aspnetcore-10.0"
631629

632-
<!-- UPDATE 10.0 - MIA API -->
633-
634630
* JS interop method calls
635631
* <xref:Microsoft.JSInterop.IJSRuntime.InvokeAsync%2A?displayProperty=nameWithType>
636632
* <xref:Microsoft.JSInterop.JSRuntimeExtensions.InvokeAsync%2A?displayProperty=nameWithType>
637633
* <xref:Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync%2A?displayProperty=nameWithType>
638634
* <xref:Microsoft.JSInterop.JSRuntime.InvokeConstructorAsync%2A>
635+
* <xref:Microsoft.JSInterop.IJSInProcessObjectReference.InvokeConstructor%2A>
639636
* <xref:Microsoft.JSInterop.JSRuntime.GetValueAsync%2A>
640637
* <xref:Microsoft.JSInterop.JSRuntime.SetValueAsync%2A>
641638
* <xref:Microsoft.JSInterop.JSRuntime.Dispose%2A>/`DisposeAsync` calls on any <xref:Microsoft.JSInterop.IJSObjectReference>.

aspnetcore/blazor/javascript-interoperability/index.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,13 +331,12 @@ JavaScript (JS) interop calls can't be issued after Blazor's SignalR circuit is
331331

332332
:::moniker range=">= aspnetcore-10.0"
333333

334-
<!-- UPDATE 10.0 - MIA API -->
335-
336334
* JS interop method calls
337335
* <xref:Microsoft.JSInterop.IJSRuntime.InvokeAsync%2A?displayProperty=nameWithType>
338336
* <xref:Microsoft.JSInterop.JSRuntimeExtensions.InvokeAsync%2A?displayProperty=nameWithType>
339337
* <xref:Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync%2A?displayProperty=nameWithType>
340338
* <xref:Microsoft.JSInterop.IJSObjectReference.InvokeConstructorAsync%2A>
339+
* <xref:Microsoft.JSInterop.IJSInProcessObjectReference.InvokeConstructor%2A>
341340
* <xref:Microsoft.JSInterop.IJSObjectReference.GetValueAsync%2A>
342341
* <xref:Microsoft.JSInterop.IJSObjectReference.SetValueAsync%2A>
343342
* `Dispose`/`DisposeAsync` calls on any <xref:Microsoft.JSInterop.IJSObjectReference>.

aspnetcore/blazor/security/blazor-web-app-with-entra.md

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ We recommend using separate registrations for apps and web APIs, even when the a
5252

5353
Register the web API (`MinimalApiJwt`) first so that you can then grant access to the web API when registering the app. The web API's tenant ID and client ID are used to configure the web API in its `Program` file. After registering the web API, expose the web API in **App registrations** > **Expose an API** with a scope name of `Weather.Get`. Record the App ID URI for use in the app's configuration.
5454

55-
Next, register the app (`BlazorWebAppEntra`) with a **Web** platform configuration and a **Redirect URI** of `https://localhost/signin-oidc` (a port isn't required). The app's tenant ID, tenant domain, and client ID, along with the web API's base address, App ID URI, and weather scope name, are used to configure the app in its `appsettings.json` file. Grant API permission to access the web API in **App registrations** > **API permissions**. If the app's security specification calls for it, you can grant admin consent for the organization to access the web API. Authorized users and groups are assigned to the app's registration in **App registrations** > **Enterprise applications**.
55+
Next, register the app (`BlazorWebAppEntra`) with a **Web** platform configuration with two entries under **Redirect URI**: `https://localhost/signin-oidc` and `https://localhost/signout-callback-oidc` (ports aren't required on these URIs). Set the **Front-channel logout URL** to `https://localhost/signout-callback-oidc` (a port isn't required). The app's tenant ID, tenant domain, and client ID, along with the web API's base address, App ID URI, and weather scope name, are used to configure the app in its `appsettings.json` file. Grant API permission to access the web API in **App registrations** > **API permissions**. If the app's security specification calls for it, you can grant admin consent for the organization to access the web API. Authorized users and groups are assigned to the app's registration in **App registrations** > **Enterprise applications**.
5656

5757
In the Entra or Azure portal's **Implicit grant and hybrid flows** app registration configuration, don't select either checkbox for the authorization endpoint to return **Access tokens** or **ID tokens**. The OpenID Connect handler automatically requests the appropriate tokens using the code returned from the authorization endpoint.
5858

@@ -205,6 +205,12 @@ builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
205205
.AddDistributedTokenCaches();
206206
```
207207

208+
The callback path (`CallbackPath`) must match the redirect URI (login callback path) configured when registering the application in the Entra or Azure portal. Paths are configured in the **Authentication** blade of the app's registration. The default value of `CallbackPath` is `/signin-oidc` for a registered redirect URI of `https://localhost/signin-oidc` (a port isn't required).
209+
210+
The <xref:Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions.SignedOutCallbackPath%2A> is the request path within the app's base path intercepted by the OpenID Connect handler where the user agent is first returned after signing out from Entra. The sample app doesn't set a value for the path because the default value of "`/signout-callback-oidc`" is used. After intercepting the request, the OpenID Connect handler redirects to the <xref:Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions.SignedOutRedirectUri%2A> or <xref:Microsoft.AspNetCore.Authentication.AuthenticationProperties.RedirectUri%2A>, if specified.
211+
212+
[!INCLUDE[](~/blazor/security/includes/secure-authentication-flows.md)]
213+
208214
:::zone-end
209215

210216
:::zone pivot="bff-pattern"
@@ -252,7 +258,7 @@ We recommend using separate registrations for apps and web APIs, even when the a
252258

253259
Register the web API (`MinimalApiJwt`) first so that you can then grant access to the web API when registering the app. The web API's tenant ID and client ID are used to configure the web API in its `Program` file. After registering the web API, expose the web API in **App registrations** > **Expose an API** with a scope name of `Weather.Get`. Record the App ID URI for use in the app's configuration.
254260

255-
Next, register the app (`BlazorWebAppEntra`) with a **Web** platform configuration and a **Redirect URI** of `https://localhost/signin-oidc` (a port isn't required). The app's tenant ID, tenant domain, and client ID, along with the web API's base address, App ID URI, and weather scope name, are used to configure the app in its `appsettings.json` file. Grant API permission to access the web API in **App registrations** > **API permissions**. If the app's security specification calls for it, you can grant admin consent for the organization to access the web API. Authorized users and groups are assigned to the app's registration in **App registrations** > **Enterprise applications**.
261+
Next, register the app (`BlazorWebAppEntra`) with a **Web** platform configuration with two entries under **Redirect URI**: `https://localhost/signin-oidc` and `https://localhost/signout-callback-oidc` (ports aren't required on these URIs). The app's tenant ID, tenant domain, and client ID, along with the web API's base address, App ID URI, and weather scope name, are used to configure the app in its `appsettings.json` file. Grant API permission to access the web API in **App registrations** > **API permissions**. If the app's security specification calls for it, you can grant admin consent for the organization to access the web API. Authorized users and groups are assigned to the app's registration in **App registrations** > **Enterprise applications**.
256262

257263
In the Entra or Azure portal's **Implicit grant and hybrid flows** app registration configuration, don't select either checkbox for the authorization endpoint to return **Access tokens** or **ID tokens**. The OpenID Connect handler automatically requests the appropriate tokens using the code returned from the authorization endpoint.
258264

@@ -435,22 +441,6 @@ The callback path (`CallbackPath`) must match the redirect URI (login callback p
435441

436442
The <xref:Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions.SignedOutCallbackPath%2A> is the request path within the app's base path intercepted by the OpenID Connect handler where the user agent is first returned after signing out from Entra. The sample app doesn't set a value for the path because the default value of "`/signout-callback-oidc`" is used. After intercepting the request, the OpenID Connect handler redirects to the <xref:Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions.SignedOutRedirectUri%2A> or <xref:Microsoft.AspNetCore.Authentication.AuthenticationProperties.RedirectUri%2A>, if specified.
437443

438-
Configure the signed-out callback path in the app's Entra registration. In the Entra or Azure portal, set the path in the **Web** platform configuration's **Redirect URI** entries:
439-
440-
> :::no-loc text="https://localhost/signout-callback-oidc":::
441-
442-
> [!NOTE]
443-
> A port isn't required for `localhost` addresses when using Entra.
444-
445-
If you don't add the signed-out callback path URI to the app's registration in Entra, Entra refuses to redirect the user back to the app and merely asks them to close their browser window.
446-
447-
<!-- UPDATE 10.0 Keep an eye on this NOTE for removal or updates.
448-
The remark on this subject is in the Program file of the
449-
Entra sample app (Blazor samples repo). -->
450-
451-
> [!NOTE]
452-
> Entra doesn't redirect a primary admin user (root account) or external user back to the Blazor application. Instead, Entra logs the user out of the app and recommends that they close all of their browser windows. For more information, see [postLogoutRedirectUri not working when authority url contains a tenant ID (`AzureAD/microsoft-authentication-library-for-js` #5783)](https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/5783#issuecomment-1465217522).
453-
454444
[!INCLUDE[](~/blazor/security/includes/secure-authentication-flows.md)]
455445

456446
### Establish the client secret

aspnetcore/blazor/security/blazor-web-app-with-oidc.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,9 +1283,6 @@ Alternatively, use the following `LogInOrOut` component, which doesn't supply a
12831283

12841284
## Token refresh
12851285

1286-
<!-- UPDATE 10.0 - Check the PU issue for 10.0 work to resolve both issues.
1287-
The docs issue is https://github.com/dotnet/AspNetCore.Docs/issues/34235. -->
1288-
12891286
The custom cookie refresher (`CookieOidcRefresher.cs`) implementation updates the user's claims automatically when they expire. The current implementation expects to receive an ID token from the token endpoint in exchange for the refresh token. The claims in this ID token are then used to overwrite the user's claims.
12901287

12911288
The sample implementation doesn't include code for requesting claims from the [UserInfo endpoint](https://openid.net/specs/openid-connect-core-1_0.html#UserInfo) on token refresh. For more information, see [`BlazorWebAppOidc AddOpenIdConnect with GetClaimsFromUserInfoEndpoint = true doesn't propogate [sic] role claims to client` (`dotnet/aspnetcore` #58826)](https://github.com/dotnet/aspnetcore/issues/58826#issuecomment-2492738142).

0 commit comments

Comments
 (0)