📜  blazor wasm 角色不起作用 (1)

📅  最后修改于: 2023-12-03 15:13:39.964000             🧑  作者: Mango

Blazor Wasm 角色不起作用

当使用 Blazor WebAssembly 时,角色授权似乎不起作用,这可能会导致不安全的应用程序。下面我们来了解该问题的解决方案。

问题描述

当使用 [Authorize] 属性或 [AuthorizeView] 组件时,即使登录用户不拥有正确的角色或要求的权限,他们仍然可以访问保护的资源。

原因探究

这是因为 Blazor WebAssembly 程序运行在客户端,无法像传统的 Web 应用程序那样对服务器进行访问。这使得在服务器端进行基于角色或授权的访问控制变得更加困难。此外,由于 Blazor WebAssembly 应用程序的本地执行特性,攻击者可以轻松地通过 JavaScript 调用和修改应用程序中的组件和对象,从而绕过角色和授权检查。

解决方案

为了解决这个问题,我们需要基于 OpenID Connect(OIDC)OAuth 2.0 协议在客户端和服务器之间建立一个安全的连接。OIDC 和 OAuth 2.0 是一种用于在不同系统之间共享身份验证和授权信息的标准协议。通过此连接,我们可以将用户凭据和访问令牌传输到服务器端以进行身份验证和授权检查。在 Blazor WebAssembly 中,我们可以使用 IdentityServer4 库来实现此目的。

IdentityServer4

IdentityServer4 是一种用于实现 OIDC 和 OAuth 2.0 协议的 .NET 库。它提供了许多服务和接口,可用于为 Blazor WebAssembly 应用程序提供身份验证和授权检查功能。使用 IdentityServer4,我们可以在客户端和服务器之间建立一个安全的连接,并确保用户只能访问其所需的资源。

要在 Blazor WebAssembly 应用程序中使用 IdentityServer4,需要完成以下步骤:

  1. 在服务器端实现 IdentityServer4。

  2. 在客户端实现 OIDC 和 OAuth 2.0,以便将用户凭据和访问令牌传输到服务器端。

  3. 配置应用程序以使用 OIDC 和 OAuth 2.0。

  4. 在客户端实现 AuthorizationMessageHandler,以便处理服务器返回的身份验证和授权信息。

下面是在 Blazor WebAssembly 应用程序中启用身份验证和授权检查的示例代码:

// Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthorizationCore();
    services.AddScoped<AuthenticationStateProvider, ServerAuthenticationStateProvider>();
    services.AddScoped<AuthorizationMessageHandler>();
    services.AddHttpClient("api", client =>
    {
        client.BaseAddress = new Uri("https://localhost:5001/api/");
    }).AddHttpMessageHandler<AuthorizationMessageHandler>();
}

public void Configure(IComponentsApplicationBuilder app)
{
    app.AddComponent<App>("app");
}

// ServerAuthenticationStateProvider.cs

public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
    var user = await _http.GetFromJsonAsync<User>("account/userinfo");
    var identity = user?.IsAuthenticated == true ? new ClaimsIdentity(user.Claims, "server") : new ClaimsIdentity();
    return new AuthenticationState(new ClaimsPrincipal(identity));
}

// App.razor

<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(Program).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
                <NotAuthorized>
                    <p>You are not authorized to access this resource.</p>
                </NotAuthorized>
            </AuthorizeRouteView>
        </Found>
        <NotFound>
            <p>Sorry, there's nothing at this address.</p>
        </NotFound>
    </Router>
</CascadingAuthenticationState>

在上面的代码中,我们使用了 AuthorizationMessageHandler 处理服务器返回的身份验证和授权信息,这使得客户端可以根据服务器的策略拒绝访问未授权资源。

总结

当使用 Blazor WebAssembly 时,角色授权很容易被绕过,从而导致应用程序不安全。为了解决这个问题,我们可以使用 IdentityServer4 库实现 OIDC 和 OAuth 2.0 协议,以便在客户端和服务器之间建立一个安全的连接。这使得我们可以安全地实现用户身份验证和授权检查功能,保护应用程序中的敏感资源。