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

Blazor Server应用从Windows身份验证迁移到AD登录方案咨询

解决方案

方案1:使用浏览器原生弹窗(HTTP Basic认证)

如果你不需要自定义登录页,想要直接触发Chrome原生的账号密码输入框,可使用ASP.NET Core内置的Basic Authentication方案,不需要自己开发登录页:

  1. 安装Microsoft.AspNetCore.Authentication.Basic Nuget包
  2. 在Program.cs中配置Basic认证服务,校验逻辑直接对接你的AD验证代码即可,浏览器遇到401响应时会自动弹出原生凭证输入窗口。

注意:Basic认证会明文传输账号密码,必须全站启用HTTPS保证安全。

方案2:现有自定义登录页的适配(解决AuthorizeView不生效问题)

你现在已经完成了AD账号校验,但是没有为用户签发合法的身份凭证,也没有将身份信息同步到Blazor的认证上下文中,所以AuthorizeView无法识别登录状态,按以下步骤修改即可:

第一步:配置Cookie认证服务和中间件

在Program.cs中添加如下配置(.NET 6+版本为例):

// 注册HttpContext访问服务
builder.Services.AddHttpContextAccessor();

// 配置Cookie认证
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.LoginPath = "/Login"; // 未登录时跳转的登录页路径
        options.Cookie.HttpOnly = true;
        options.Cookie.SameSite = SameSiteMode.Strict;
        options.ExpireTimeSpan = TimeSpan.FromHours(8); // 登录有效期
        options.SlidingExpiration = true; // 活跃状态自动续期
    });

builder.Services.AddAuthorization();

// --- 中间件顺序不能乱 ---
var app = builder.Build();
// ... 其他中间件(静态文件、路由等)
app.UseRouting();

app.UseAuthentication(); // 必须在Authorization之前
app.UseAuthorization();

// ... 后面的Blazor Hub、端点映射
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

同时确认你已完全禁用IIS/项目配置中的Windows身份验证,开启匿名身份验证。

第二步:修改Login页面的登录逻辑

你需要在AD校验通过后,为用户签发身份凭证并写入Cookie,修改代码如下:
首先注入IHttpContextAccessor:

@inject IHttpContextAccessor _httpContextAccessor

然后修改HandleValidSubmit方法:

// 改为异步方法
private async Task HandleValidSubmit()
{
    DirectoryEntry entry = new DirectoryEntry("LDAP://myldap");
    entry.Username = userCredentials.UserName;
    entry.Password = userCredentials.Password;

    DirectorySearcher search = new DirectorySearcher(entry);
    search.Filter = "(SAMAccountName=" + userCredentials.UserName.Replace("'", "''") + ")"; // 简单防LDAP注入
    SearchResult result = search.FindOne();

    if (result == null)
    {
        showAuthenticationError = true;
        authenticationErrorText = "用户名或密码错误";
        return;
    }
    
    // 构造用户身份Claims,可从AD查询结果中提取更多字段(如显示名、角色、邮箱等)加入
    var claims = new List<Claim>
    {
        new Claim(ClaimTypes.Name, userCredentials.UserName),
        // 示例:添加AD中的显示名 new Claim(ClaimTypes.GivenName, result.Properties["givenname"][0].ToString()),
        // 示例:添加角色 new Claim(ClaimTypes.Role, "管理员")
    };
    
    // 构造身份凭证
    var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
    var principal = new ClaimsPrincipal(identity);
    
    // 签发登录Cookie
    await _httpContextAccessor.HttpContext.SignInAsync(
        CookieAuthenticationDefaults.AuthenticationScheme, 
        principal,
        new AuthenticationProperties
        {
            IsPersistent = true, // 关闭浏览器是否保留登录状态
            ExpiresUtc = DateTimeOffset.UtcNow.AddHours(8)
        });
    
    // 跳转到首页
    navManager.NavigateTo("/Index", true);
}

第三步:配置App.razor传递认证状态

确认你的App.razor最外层包裹了<CascadingAuthenticationState>,这样才能将身份信息传递给所有子组件(包括AuthorizeView):

<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(App).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
                <NotAuthorized>
                    <p>无权访问该页面</p>
                </NotAuthorized>
            </AuthorizeRouteView>
        </Found>
        <NotFound>
            <PageTitle>未找到页面</PageTitle>
            <LayoutView Layout="@typeof(MainLayout)">
                <p>抱歉,您访问的页面不存在。</p>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>

完成以上修改后,AuthorizeView即可正常识别用户登录状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 20:15:01