Prerendered hosted WASM auth updates (#23973)
parent
c9f6d1bf34
commit
86c74e4220
|
@ -129,6 +129,9 @@ To set up prerendering for a hosted Blazor WebAssembly app:
|
|||
<component type="typeof(App)" render-mode="WebAssemblyPrerendered" />
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Prerendering isn't supported for authentication endpoints (`/authentication/` path segment). For more information, see <xref:blazor/security/webassembly/additional-scenarios#support-prerendering-with-authentication>.
|
||||
|
||||
1. In endpoint mapping of the **`Server`** project in `Program.cs`, change the fallback from the `index.html` file to the `_Host.cshtml` page:
|
||||
|
||||
Delete:
|
||||
|
|
|
@ -5,7 +5,7 @@ description: Learn how to configure Blazor WebAssembly for additional security s
|
|||
monikerRange: '>= aspnetcore-3.1'
|
||||
ms.author: riande
|
||||
ms.custom: mvc
|
||||
ms.date: 11/09/2021
|
||||
ms.date: 11/18/2021
|
||||
no-loc: [Home, Privacy, Kestrel, appsettings.json, "ASP.NET Core Identity", cookie, Cookie, Blazor, "Blazor Server", "Blazor WebAssembly", "Identity", "Let's Encrypt", Razor, SignalR]
|
||||
uid: blazor/security/webassembly/additional-scenarios
|
||||
---
|
||||
|
@ -814,7 +814,7 @@ Prerendering content that requires authentication and authorization isn't curren
|
|||
* Prerenders paths for which authorization isn't required.
|
||||
* Doesn't prerender paths for which authorization is required.
|
||||
|
||||
For the client (**`Client`**) app's `Program.cs`, factor common service registrations into a separate method (for example, `ConfigureCommonServices`). Common services are those that the developer registers for use by both the client and server (**`Server`**) apps.
|
||||
For the client (**`Client`**) app's `Program.cs`, factor common service registrations into a separate method (for example, create a `ConfigureCommonServices` method in the **`Client`** project). Common services are those that the developer registers for use by both the client and server (**`Server`**) apps.
|
||||
|
||||
```csharp
|
||||
public static void ConfigureCommonServices(IServiceCollection services)
|
||||
|
@ -836,7 +836,7 @@ ConfigureCommonServices(builder.Services);
|
|||
await builder.Build().RunAsync();
|
||||
```
|
||||
|
||||
In the server app's `Program.cs` file, register the following additional services and call `ConfigureCommonServices`:
|
||||
In the **`Server`** app's `Program.cs` file, register the following additional services and call `ConfigureCommonServices`:
|
||||
|
||||
```csharp
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
|
@ -853,32 +853,32 @@ builder.Services.AddScoped<SignOutSessionStateManager>();
|
|||
Client.Program.ConfigureCommonServices(services);
|
||||
```
|
||||
|
||||
In the server app's `Program.cs`, replace [`app.MapFallbackToFile("index.html")`](xref:Microsoft.AspNetCore.Builder.StaticFilesEndpointRouteBuilderExtensions.MapFallbackToFile%2A) with [`app.MapFallbackToPage("/_Host")`](xref:Microsoft.AspNetCore.Builder.RazorPagesEndpointRouteBuilderExtensions.MapFallbackToPage%2A):
|
||||
In the **`Server`** app's `Program.cs` file, replace [`app.MapFallbackToFile("index.html")`](xref:Microsoft.AspNetCore.Builder.StaticFilesEndpointRouteBuilderExtensions.MapFallbackToFile%2A) with [`app.MapFallbackToPage("/_Host")`](xref:Microsoft.AspNetCore.Builder.RazorPagesEndpointRouteBuilderExtensions.MapFallbackToPage%2A):
|
||||
|
||||
```csharp
|
||||
app.MapControllers();
|
||||
app.MapFallbackToPage("/_Host");
|
||||
```
|
||||
|
||||
In the server app, create a `Pages` folder if it doesn't exist. Create a `_Host.cshtml` page inside the server app's `Pages` folder. Paste the contents from the client app's `wwwroot/index.html` file into the `Pages/_Host.cshtml` file. Update the file's contents:
|
||||
In the **`Server`** app, create a `Pages` folder if it doesn't exist. Create a `_Host.cshtml` page inside the **`Server`** app's `Pages` folder. Paste the contents from the client app's `wwwroot/index.html` file into the `Pages/_Host.cshtml` file. Update the file's contents:
|
||||
|
||||
* Add `@page "_Host"` to the top of the file.
|
||||
* Replace the `<div id="app">Loading...</div>` tag with the following:
|
||||
|
||||
```cshtml
|
||||
<div id="app">
|
||||
@if (!HttpContext.Request.Path.StartsWithSegments("/authentication"))
|
||||
{
|
||||
<component type="typeof({CLIENT APP ASSEMBLY NAME}.App)"
|
||||
render-mode="Static" />
|
||||
}
|
||||
else
|
||||
@if (HttpContext.Request.Path.StartsWithSegments("/authentication"))
|
||||
{
|
||||
<text>Loading...</text>
|
||||
}
|
||||
else
|
||||
{
|
||||
<component type="typeof({CLIENT APP ASSEMBLY NAME}.App)"
|
||||
render-mode="WebAssemblyPrerendered" />
|
||||
}
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
In the preceding example, the placeholder `{CLIENT APP ASSEMBLY NAME}` is the client app's assembly name (for example `BlazorSample.Client`).
|
||||
|
||||
## Options for hosted apps and third-party login providers
|
||||
|
@ -1908,18 +1908,18 @@ In the server app, create a `Pages` folder if it doesn't exist. Create a `_Host.
|
|||
|
||||
```cshtml
|
||||
<div id="app">
|
||||
@if (!HttpContext.Request.Path.StartsWithSegments("/authentication"))
|
||||
{
|
||||
<component type="typeof({CLIENT APP ASSEMBLY NAME}.App)"
|
||||
render-mode="Static" />
|
||||
}
|
||||
else
|
||||
@if (HttpContext.Request.Path.StartsWithSegments("/authentication"))
|
||||
{
|
||||
<text>Loading...</text>
|
||||
}
|
||||
else
|
||||
{
|
||||
<component type="typeof({CLIENT APP ASSEMBLY NAME}.App)"
|
||||
render-mode="WebAssemblyPrerendered" />
|
||||
}
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
In the preceding example, the placeholder `{CLIENT APP ASSEMBLY NAME}` is the client app's assembly name (for example `BlazorSample.Client`).
|
||||
|
||||
## Options for hosted apps and third-party login providers
|
||||
|
@ -2949,18 +2949,18 @@ In the server app, create a `Pages` folder if it doesn't exist. Create a `_Host.
|
|||
|
||||
```cshtml
|
||||
<app>
|
||||
@if (!HttpContext.Request.Path.StartsWithSegments("/authentication"))
|
||||
{
|
||||
<component type="typeof({CLIENT APP ASSEMBLY NAME}.App)"
|
||||
render-mode="Static" />
|
||||
}
|
||||
else
|
||||
@if (HttpContext.Request.Path.StartsWithSegments("/authentication"))
|
||||
{
|
||||
<text>Loading...</text>
|
||||
}
|
||||
else
|
||||
{
|
||||
<component type="typeof({CLIENT APP ASSEMBLY NAME}.App)"
|
||||
render-mode="WebAssemblyPrerendered" />
|
||||
}
|
||||
</app>
|
||||
```
|
||||
|
||||
|
||||
In the preceding example, the placeholder `{CLIENT APP ASSEMBLY NAME}` is the client app's assembly name (for example `BlazorSample.Client`).
|
||||
|
||||
## Options for hosted apps and third-party login providers
|
||||
|
|
|
@ -34,6 +34,9 @@ Other options for authenticating SPAs exist, such as the use of SameSite cookies
|
|||
* Tokens with OAuth and OIDC don't rely on the user agent behaving correctly to ensure that the app is secure.
|
||||
* Token-based protocols, such as OAuth and OIDC, allow for authenticating and authorizing hosted and standalone apps with the same set of security characteristics.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> [Prerendering](xref:blazor/components/prerendering-and-integration) isn't supported for authentication endpoints (`/authentication/` path segment). For more information, see <xref:blazor/security/webassembly/additional-scenarios#support-prerendering-with-authentication>.
|
||||
|
||||
## Authentication process with OIDC
|
||||
|
||||
The [`Microsoft.AspNetCore.Components.WebAssembly.Authentication`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.WebAssembly.Authentication) library offers several primitives to implement authentication and authorization using OIDC. In broad terms, authentication works as follows:
|
||||
|
|
Loading…
Reference in New Issue