.NET MAUI Blazor Hybrid 和带有 ASP.NET Core 的 Web 应用程序 Identity

此示例应用程序演示了如何使用 .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 组件)。

  1. 克隆此存储库或下载存储库的 ZIP 存档。 有关更多信息,请参阅 如何下载示例
  2. 确保您已安装 .NET 9 和 MAUI 工作负载(.NET MAUI文档)。
  3. 在 Visual Studio(2022 或更高版本)或 VS Code 中打开解决方案, .NET MAUI 并安装了扩展。
  4. MauiBlazorWeb MAUI 项目设置为启动项目。 在 Visual Studio 中,右键单击项目,然后选择 Set as Startup Project
  5. MauiBlazorWeb.Web启动项目而不进行调试。 在 Visual Studio 中,右键单击项目,然后选择 Debug>启动但不调试)。
  6. 通过在浏览器中导航到Identity来检查https://localhost:7157/swagger终端节点。
  7. https://localhost:7157/account/register导航到 以在 Blazor Web App中注册用户。 用户注册后,立即使用 UI 中的 Click here to confirm your account (单击此处确认您的账户 ) 链接确认用户的电子邮件地址,因为真正的电子邮件发件人未注册账户确认。
  8. 启动 ()F5 MAUI MauiBlazorWeb 项目。 您可以将调试目标设置为 Windows 或 Android 仿真器。
  9. 请注意, Home 您只能看到 和 Login 页面。
  10. 使用您注册的用户登录。
  11. 请注意,您现在可以看到 shared CounterWeather pages。
  12. 注销并注意,您只能再次看到 HomeLogin 页面。
  13. 在浏览器中导航到 , https://localhost:7157/ Web 应用程序的行为相同。

共享 UI

共享 UI 位于 MauiBlazorWeb.Shared 项目中。 此项目包含在 Razor MAUI 和 Blazor Web App 项目之间共享的组件(HomeCounter 和 Weather 页面)。 组件 CounterWeather 组件受 [Authorize] 属性保护,因此用户除非登录到应用程序,否则无法导航到它们。

在组件 ()Razor 和组件 ()Counter 文件顶部的MauiBlazorWeb.Shared/Pages/Counter.razorMauiBlazorWeb.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 端点设置了对以下项的调用:

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 ()MauiAuthenticationStateProviderMauiProgram.cs中注册:

builder.Services.AddScoped<MauiAuthenticationStateProvider>();

MauiAuthenticationStateProvider当应用程序需要 AuthenticationStateProvider时,请使用 :

builder.Services.AddScoped<AuthenticationStateProvider>(s => 
    (MauiAuthenticationStateProvider)
        s.GetRequiredService<MauiAuthenticationStateProvider>());