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

ASP.NET Core 6集成Azure AD认证自定义登录路径失效问题

问题根因

你之前的配置不生效有两个核心原因:

  1. AddMicrosoftIdentityWebApp 默认会重写Cookie认证的OnChallenge事件,内置逻辑是直接发起OIDC挑战跳转到Azure AD登录页,完全忽略你配置的LoginPath参数。
  2. 你当前将OpenIdConnectDefaults.AuthenticationScheme设为了默认认证方案,访问受保护页面时会直接触发OIDC挑战,根本不会走到Cookie认证的跳转逻辑。
可行实现步骤

1. 调整Program.cs认证服务配置

核心思路是将Cookie认证设为默认方案,拦截默认的挑战跳转逻辑,给Azure AD OIDC认证分配独立的方案名,避免它接管默认跳转。

builder.Services
    // 默认认证、挑战、注销方案统一指定为Cookie认证,不要用OIDC作为默认
    .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
    {
        options.LoginPath = new PathString("/Login/Login");
        // 核心:重写挑战事件,阻止默认跳Azure AD的逻辑
        options.Events.OnChallenge = context =>
        {
            // 已经在登录页的话无需重复跳转
            if (context.Request.Path.StartsWithSegments("/Login/Login"))
            {
                return Task.CompletedTask;
            }
            // 携带原始访问地址,登录完成后可直接跳回
            var returnUrl = Uri.EscapeDataString(context.Request.Path + context.Request.QueryString);
            context.Response.Redirect($"/Login/Login?returnUrl={returnUrl}");
            context.HandleResponse();
            return Task.CompletedTask;
        };
    })
    // 独立注册Azure AD OIDC认证,指定独立方案名
    .AddMicrosoftIdentityWebApp(
        configureMicrosoftIdentityOptions: options =>
        {
            builder.Configuration.Bind("AzureAd", options);
            options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        },
        cookieScheme: CookieAuthenticationDefaults.AuthenticationScheme,
        // 给OIDC方案单独命名,后续触发Azure AD登录时用
        openIdConnectScheme: "AzureAd"
    )
    .EnableTokenAcquisitionToCallDownstreamApi(new[] { "user.read" })
    .AddInMemoryTokenCaches();

注意:不要使用builder.Services.ConfigureApplicationCookie修改配置,AddMicrosoftIdentityWebApp注册的Cookie实例和默认ApplicationCookie不是同一个对象,单独配置不会生效。

2. 配置登录页相关Action

首先给登录页Action加上匿名访问标记:

[AllowAnonymous]
[Route("/Login/Login")]
public IActionResult Login(string returnUrl = null)
{
    ViewData["ReturnUrl"] = returnUrl;
    return View();
}

在登录视图中提供两个登录入口:

  • 本地账号登录:走自定义的用户名密码校验逻辑,校验通过后调用HttpContext.SignInAsync写入身份票据到默认Cookie方案即可
  • Azure AD登录:单独加一个Action触发OIDC挑战,不要直接在默认流程里触发
[AllowAnonymous]
[HttpPost("/Login/AzureAdSignIn")]
public IActionResult AzureAdSignIn(string returnUrl = null)
{
    var redirectUri = Url.Action("LoginCallback", "Login", new { returnUrl });
    // 触发我们单独命名的AzureAd方案的挑战
    return Challenge(new AuthenticationProperties { RedirectUri = redirectUri }, "AzureAd");
}

3. 补充注意点

  • 两种登录方式最终生成的身份票据都要写入同一个默认Cookie认证方案,后续请求鉴权时不需要区分用户的登录来源。
  • 如果需要加注销逻辑,同时注销Cookie和Azure AD会话即可。
  • 如果你之前给Controller/Action加了指定认证方案的[Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)]标记,要改成默认的[Authorize],否则还是会直接触发OIDC挑战跳微软登录页。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:33:17