You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8 Blazor服务器端渲染应用中基于函数结果实现用户认证

Blazor Server端基于自定义数据库验证的认证实现方案

1. 实现自定义AuthorizationStateProvider

通过继承AuthenticationStateProvider替换框架默认认证逻辑,将你的数据库验证结果转换为Blazor可识别的认证状态:

using Microsoft.AspNetCore.Components.Authorization;
using System.Security.Claims;

public class CustomAuthStateProvider : AuthenticationStateProvider
{
    public override Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        // 调用数据库验证逻辑
        var isLoggedIn = Helper.IsUserLoggedIn();
        
        ClaimsPrincipal user;
        if (isLoggedIn)
        {
            // 已登录:构造基础身份信息(后续可扩展角色/权限Claims)
            var identity = new ClaimsIdentity(new[]
            {
                new Claim(ClaimTypes.NameIdentifier, "当前用户ID"),
                new Claim(ClaimTypes.Name, "当前用户名")
            }, "CustomAuth");
            user = new ClaimsPrincipal(identity);
        }
        else
        {
            // 未登录:返回匿名身份
            user = new ClaimsPrincipal(new ClaimsIdentity());
        }

        return Task.FromResult(new AuthenticationState(user));
    }

    // 可选:登录/登出后主动更新认证状态
    public void UpdateAuthState(bool isLoggedIn)
    {
        var user = isLoggedIn 
            ? new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, "用户ID") }, "CustomAuth"))
            : new ClaimsPrincipal(new ClaimsIdentity());
        
        NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(user)));
    }
}

2. 注册自定义认证服务

在Program.cs中替换默认的认证状态提供者:

builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();
builder.Services.AddAuthorization();

3. 全局访问控制与跳转

在App.razor中用CascadingAuthenticationState包裹根组件,结合AuthorizeRouteView实现路由级别的权限拦截:

<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(App).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
                <NotAuthorized>
                    <!-- 未登录时跳转至组织登录页 -->
                    @{
                        NavigationManager.NavigateTo("/组织登录页路径", forceLoad: true);
                    }
                </NotAuthorized>
            </AuthorizeRouteView>
            <FocusOnNavigate RouteData="@routeData" Selector="h1" />
        </Found>
        <NotFound>
            <PageTitle>Not found</PageTitle>
            <LayoutView Layout="@typeof(MainLayout)">
                <p role="alert">Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>

@inject NavigationManager NavigationManager

4. 组件内细粒度权限控制

单个组件内可直接用AuthorizedView区分登录状态:

<AuthorizedView>
    <Authorized>
        <p>欢迎登录,当前用户:@context.User.Identity.Name</p>
        <!-- 已登录可见内容 -->
    </Authorized>
    <NotAuthorized>
        <p>请先完成登录</p>
        <!-- 未登录可见内容 -->
    </NotAuthorized>
</AuthorizedView>

@inject AuthenticationStateProvider AuthStateProvider

最佳实践与扩展建议

  • 所有认证逻辑集中在CustomAuthStateProvider,避免组件直接调用Helper.IsUserLoggedIn(),保持代码内聚。
  • 若Helper.IsUserLoggedIn()为异步方法,直接在GetAuthenticationStateAsync中await调用即可。
  • 后续扩展角色/权限时,只需在构造ClaimsPrincipal时添加ClaimTypes.Role或自定义权限Claims,即可使用[Authorize(Roles = "Admin")]特性或AuthorizeView(Roles = "Admin")实现细粒度控制。
  • 登录成功后调用CustomAuthStateProvider.UpdateAuthState(true),主动通知框架更新认证状态,无需刷新页面。

内容的提问来源于stack exchange,提问作者Vivian River

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 20:18:19