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

ASP.NET Core 6如何将Windows认证作为密码登录替代方案

ASP.NET Core 6 内外网差异化AD+Cookie统一认证实现方案

核心思路:不要将Negotiate(Windows/AD)认证配置为全局默认认证方案,仅将其作为AD专用登录端点的独立认证手段,全局所有业务接口统一使用CookieAuthentication作为默认认证方案,即可完全匹配你的所有需求。

1. 认证服务注册配置

在Program.cs中注册认证服务时,默认认证方案指定为Cookie认证,额外注册Negotiate认证但不将其设为默认,避免全局触发AD认证弹窗:

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.LoginPath = "/Account/Login";
        options.AccessDeniedPath = "/Account/AccessDenied";
        // 其余Cookie配置(过期时长、HttpOnly、Secure策略等)按需配置即可
    })
    .AddNegotiate(); // 仅注册AD认证能力,不做全局启用

该配置下,所有未单独指定认证方案的接口,默认都会走Cookie校验逻辑,外网用户完全感知不到AD认证模块的存在。

2. 登录页内外网差异化渲染

在登录页的控制器/PageModel中,自行实现内网来源判断逻辑:

  • 可基于请求IP判断:校验当前请求IP是否属于内网私网段(10.0.0.0/8、172.16.0.0/12、192.168.0.0/16),或你自定义的内网IP白名单
  • 可基于访问域名判断:校验请求Host是否为内网专用域名/IP
    若判断为内网来源,页面渲染「使用Active Directory登录」按钮,按钮跳转至专用AD登录接口;若为外网来源,仅渲染账号密码登录表单即可。

3. 专用AD登录端点实现

单独开发AD登录接口,仅该接口启用Negotiate认证,其余逻辑完全由你自定义控制:

[HttpGet("/account/ad-login")]
[Authorize(AuthenticationSchemes = NegotiateDefaults.AuthenticationScheme)]
public async Task<IActionResult> AdLogin()
{
    // 从Negotiate认证结果中提取当前AD账号名
    var adAccount = User.Identity?.Name;
    if (string.IsNullOrWhiteSpace(adAccount))
    {
        await HttpContext.SignOutAsync(NegotiateDefaults.AuthenticationScheme);
        return RedirectToAction("Login", new { error = "AD身份验证失败,请重试" });
    }

    // 校验AD账号是否存在于你的Login表中
    var validUser = await _dbContext.Login
        .FirstOrDefaultAsync(u => u.AdAccount.Equals(adAccount, StringComparison.OrdinalIgnoreCase));
    if (validUser == null)
    {
        // 清除Negotiate临时认证结果,避免浏览器反复弹出认证框
        await HttpContext.SignOutAsync(NegotiateDefaults.AuthenticationScheme);
        return RedirectToAction("Login", new { error = "当前AD账号未开通系统访问权限,请联系管理员" });
    }

    // 构造与密码登录完全一致的用户身份声明,保证后续认证逻辑统一
    var userClaims = new List<Claim>
    {
        new Claim(ClaimTypes.NameIdentifier, validUser.Id.ToString()),
        new Claim(ClaimTypes.Name, validUser.UserName),
        // 其余声明(角色、部门、权限标识等)与密码登录逻辑保持完全一致即可
    };
    var userIdentity = new ClaimsIdentity(userClaims, CookieAuthenticationDefaults.AuthenticationScheme);
    var principal = new ClaimsPrincipal(userIdentity);

    // 写入统一的认证Cookie
    await HttpContext.SignInAsync(
        CookieAuthenticationDefaults.AuthenticationScheme,
        principal,
        new AuthenticationProperties
        {
            IsPersistent = true // 持久化配置与密码登录保持一致即可
        });

    // 清除Negotiate临时认证身份,后续请求完全通过Cookie完成校验
    await HttpContext.SignOutAsync(NegotiateDefaults.AuthenticationScheme);

    return Redirect("/");
}

方案特性说明

  • 所有业务接口统一使用[Authorize]特性即可,无需单独指定认证方案,密码登录用户、AD登录用户的后续身份校验逻辑完全一致,没有分支差异
  • 外网用户既看不到AD登录入口,就算手动访问AD登录接口,也会因为外网环境不支持域认证直接跳转回登录页,不存在安全风险
  • AD登录的准入逻辑完全由你控制,只有存在于Login表中的AD账号才能完成登录,不会出现Negotiate认证通过就直接放行的问题
  • 扩展灵活,如果需要新增AD账号绑定、首次登录补全信息等逻辑,直接在AdLogin接口中扩展即可,不影响现有认证体系

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 19:27:27