ASP.NET Core 6集成Azure AD认证自定义登录路径失效问题
问题根因
你之前的配置不生效有两个核心原因:
AddMicrosoftIdentityWebApp默认会重写Cookie认证的OnChallenge事件,内置逻辑是直接发起OIDC挑战跳转到Azure AD登录页,完全忽略你配置的LoginPath参数。- 你当前将
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
相关产品推荐
相关产品推荐

