此示例应用程序演示了如何使用 .NET MAUIBlazor Hybrid 构建使用 Blazor Web App ASP.NET Core Identity的应用程序。 它展示了如何共享通用 UI 并与 ASP.NET Core Identity 本地帐户进行身份验证。 尽管使用了 ASP.NET Core Identity ,但您可以从 MAUI Blazor Hybrid 客户端将此模式用于任何身份验证提供程序。
示例 :
- 设置 UI 以根据用户身份验证显示或隐藏页面。
- 为远程客户端设置 ASP.NET Core Identity 终端节点。
- 从 MAUI 客户端登录用户、注销用户并刷新令牌。
- 在安全设备存储中保存和检索令牌。
- 从客户端调用安全终结点 ()
/api/weather
以获取天气数据。
先决条件和初步步骤
有关先决条件和初步步骤,请参阅 构建 .NET MAUIBlazor Hybrid 应用程序。 我们建议先使用 MAUI Blazor Hybrid 教程设置本地系统以进行 MAUI 开发,然后再使用本文中的指南和示例应用。
示例应用
在dotnet/blazor-samples
文件夹中获取示例应用程序。
示例应用程序是一个入门解决方案,其中包含一个本机跨平台 MAUI Blazor Hybrid 应用程序、一个 Blazor Web App和一个 Razor 类库 (RCL),其中包含本机应用程序和 Web 应用程序使用的共享 UI(Razor 组件)。
- 克隆此存储库或下载存储库的 ZIP 存档。 有关更多信息,请参阅 如何下载示例。
- 确保您已安装 .NET 9 和 MAUI 工作负载(.NET MAUI文档)。
- 在 Visual Studio(2022 或更高版本)或 VS Code 中打开解决方案, .NET MAUI 并安装了扩展。
- 将
MauiBlazorWeb
MAUI 项目设置为启动项目。 在 Visual Studio 中,右键单击项目,然后选择 Set as Startup Project。 -
MauiBlazorWeb.Web
启动项目而不进行调试。 在 Visual Studio 中,右键单击项目,然后选择 Debug>启动但不调试)。 - 通过在浏览器中导航到Identity来检查
https://localhost:7157/swagger
终端节点。 -
https://localhost:7157/account/register
导航到 以在 Blazor Web App中注册用户。 用户注册后,立即使用 UI 中的 Click here to confirm your account (单击此处确认您的账户 ) 链接确认用户的电子邮件地址,因为真正的电子邮件发件人未注册账户确认。 - 启动 ()
F5
MAUIMauiBlazorWeb
项目。 您可以将调试目标设置为 Windows 或 Android 仿真器。 - 请注意,
Home
您只能看到 和Login
页面。 - 使用您注册的用户登录。
- 请注意,您现在可以看到 shared
Counter
和Weather
pages。 - 注销并注意,您只能再次看到
Home
和Login
页面。 - 在浏览器中导航到 ,
https://localhost:7157/
Web 应用程序的行为相同。
共享 UI
共享 UI 位于 MauiBlazorWeb.Shared
项目中。 此项目包含在 Razor MAUI 和 Blazor Web App 项目之间共享的组件(HomeCounter 和 Weather 页面)。 组件 Counter
和 Weather
组件受 [Authorize]
属性保护,因此用户除非登录到应用程序,否则无法导航到它们。
在组件 ()Razor 和组件 ()Counter
文件顶部的MauiBlazorWeb.Shared/Pages/Counter.razor
MauiBlazorWeb.Shared/Pages/Weather.razor
中:
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize]
MAUI 应用和 Blazor Web App 路由
该 Routes
组件使用 an AuthorizeRouteView 根据用户的身份验证状态路由用户。 如果用户未通过身份验证,则会将其重定向到该 Login
页面。 有关详细信息,请参阅 ASP.NET Core Blazor 身份验证和授权。
在 MauiBlazorWeb.Web/Components/Routes.razor
中:
<AuthorizeRouteView ...>
<Authorizing>
Authorizing...
</Authorizing>
<NotAuthorized>
<Login />
</NotAuthorized>
</AuthorizeRouteView>
该NavMenu
组件包含导航菜单,该菜单使用组件AuthorizeView
根据用户的身份验证状态显示或隐藏链接。
在 MauiBlazorWeb.Web/Components/Layout/NavMenu.razor
中:
<AuthorizeView>
<NotAuthorized>
...
</NotAuthorized>
<Authorized>
...
</Authorized>
</AuthorizeView>
服务器项目
Blazor Web App示例应用程序的项目 ()MauiBlazorWeb.Web
包含 ASP.NET Core Identity 页面,并使用 SignInManager<TUser> framework 类来管理服务器上的登录名和用户。 为了使 MAUI 客户端 (或任何外部客户端) 进行身份验证, Identity 必须注册并公开终结点。 在该 Program
文件中, Identity 端点设置了对以下项的调用:
- AddIdentityApiEndpoints
- MapIdentityApi
-
MapAdditionalIdentityEndpoints
(MauiBlazorWeb.Web/Components/Account/IdentityComponentsEndpointRouteBuilderExtensions.cs
)。
在 MauiBlazorWeb.Web/Program.cs
中:
builder.Services.AddIdentityApiEndpoints<ApplicationUser>(...)
.AddEntityFrameworkStores<ApplicationDbContext>();
...
app.MapGroup("/identity").MapIdentityApi<ApplicationUser>();
...
app.MapAdditionalIdentityEndpoints();
重要
当您使用 Identity 从SignInManager<TUser>项目模板创建项目时,会自动生成 ASP.NET Core Blazor Web App pages 以及用于管理登录名和用户的框架类的实施。
本文重点介绍如何使用提供的示例应用程序;但是, Blazor Web App 从模板创建新项目时,必须删除生成的对 AddIdentityCookies on AddAuthentication的调用。 在实现 API 时(例如 MapAdditionalIdentityEndpoints
在示例应用程序中),该调用不是必需的,如果保留在应用程序中,则会导致错误。
从 MAUI 客户端登录
Login
组件 (/identity/login
endpoint) 是用户登录的位置。 该组件注入 MauiAuthenticationStateProvider
()MauiBlazorWeb/Services/MauiAuthenticationStateProvider.cs
并使用 对 AuthenticationStateProvider 用户进行身份验证,如果成功,则将其重定向到主页。 当状态更改时, AuthorizeView
组件 会根据用户的身份验证状态显示相应的链接。
在 MauiBlazorWeb/Components/Pages/Login.razor
中:
private async Task LoginUser()
{
await AuthStateProvider.LogInAsync(LoginModel);
if (AuthStateProvider.LoginStatus != LoginStatus.Success)
{
loginFailureHidden = false;
return;
}
Navigation.NavigateTo("");
}
注释
此示例仅在 MAUI 客户端上实现登录和注销页面,但您可以针对公开 Identity 的终端节点构建 Register 和其他管理页面,以获得更多功能。 有关 Identity 终端节点的更多信息,请参阅 用于 Identity 保护 SPA 的 Web API 后端。
MAUI 身份验证状态提供程序 ()MauiAuthenticationStateProvider
该 MauiAuthenticationStateProvider
类负责管理用户的身份验证状态并向应用程序提供 AuthenticationState 。 该 MauiAuthenticationStateProvider
类使用 an HttpClient 向服务器发出请求以验证用户。 有关详细信息,请参阅 ASP.NET Core Blazor Hybrid 身份验证和授权。
在 MauiBlazorWeb/Services/MauiAuthenticationStateProvider.cs
中:
private async Task<ClaimsPrincipal> LoginWithProviderAsync(LoginRequest loginModel)
{
var authenticatedUser = _defaultUser;
LoginStatus = LoginStatus.None;
try
{
// Call the Login endpoint and pass the email and password
var httpClient = HttpClientHelper.GetHttpClient();
var loginData = new { loginModel.Email, loginModel.Password };
using var response = await httpClient.PostAsJsonAsync(HttpClientHelper.LoginUrl,
loginData);
LoginStatus =
response.IsSuccessStatusCode ? LoginStatus.Success : LoginStatus.Failed;
if (LoginStatus == LoginStatus.Success)
{
// Save token to secure storage so the user doesn't have to login
// every time
var token = await response.Content.ReadAsStringAsync();
_accessToken = await TokenStorage.SaveTokenToSecureStorageAsync(token,
loginModel.Email);
authenticatedUser = CreateAuthenticatedUser(loginModel.Email);
LoginStatus = LoginStatus.Success;
}
else
{
LoginFailureMessage = "Invalid Email or Password. Please try again.";
LoginStatus = LoginStatus.Failed;
}
}
catch (Exception ex)
{
Debug.WriteLine($"Error logging in: {ex}");
LoginFailureMessage = "Server error.";
LoginStatus = LoginStatus.Failed;
}
return authenticatedUser;
}
该 MauiAuthenticationStateProvider
类使用 HttpClientHelper
()MauiBlazorWeb/Services/HttpClientHelper.cs
处理通过模拟器和模拟器调用 localhost 进行测试。 有关从仿真器和模拟器调用本地服务的更多信息,请参阅从 Android 仿真器和 iOS 模拟器连接到本地 Web 服务(.NET MAUI文档)。
MAUI 身份验证状态提供程序还使用 TokenStorage
类 (MauiBlazorWeb/Services/TokenStorage.cs
),该类使用 SecureStorage
API(.NET MAUI 文档) 将用户的令牌安全地存储在设备上。 它会在令牌过期时刷新令牌,以避免用户登录。
MAUI MauiProgram
文件
MAUI 项目的文件 MauiProgram
()MauiProgram.cs
是在 DI 容器中注册的位置 MauiAuthenticationStateProvider
。 此外,还注册了 Authorization 核心组件,其中定义了 component 等 AuthorizeView
API。
在 MauiBlazorWeb/MauiProgram.cs
中,通过调用 AddAuthorizationCore来添加核心功能:
builder.Services.AddAuthorizationCore();
应用程序的自定义 AuthenticationStateProvider ()MauiAuthenticationStateProvider
在 MauiProgram.cs
中注册:
builder.Services.AddScoped<MauiAuthenticationStateProvider>();
MauiAuthenticationStateProvider
当应用程序需要 AuthenticationStateProvider时,请使用 :
builder.Services.AddScoped<AuthenticationStateProvider>(s =>
(MauiAuthenticationStateProvider)
s.GetRequiredService<MauiAuthenticationStateProvider>());