ASP.NET Core 6 AzureAD认证:自定义登录页跳转而非直接OAuth登录
解决方案
你的问题核心是两次调用AddAuthentication导致默认认证方案被覆盖,后添加的OpenIdConnect成为了默认方案,所以未认证请求会直接跳转到Azure AD的登录页,而非你自定义的页面。要实现「全站保护+仅开放自定义登录页匿名访问」,可以按以下步骤调整代码:
1. 正确配置认证服务
只调用一次AddAuthentication,设置默认的Cookie认证方案,同时添加OpenIdConnect并关联到该Cookie:
// 设置默认认证方案为Cookie builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) // 配置Cookie认证,指定未认证时跳转到自定义登录页 .AddCookie(options => { options.LoginPath = "/Account/Login"; options.Cookie.Name = "YourAppAuthCookie"; // 可选,自定义Cookie名称 }) // 添加Azure AD的OpenIdConnect认证,关联到上面的Cookie方案 .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"), openIdConnectScheme: OpenIdConnectDefaults.AuthenticationScheme, cookieScheme: CookieAuthenticationDefaults.AuthenticationScheme);
2. 开放自定义登录页的匿名访问
你需要确保/Account/Login路径允许匿名访问,避免重定向死循环,有两种实现方式:
方式一:全局路由配置(推荐)
在Program.cs中,对全局路由要求认证,单独开放登录页的匿名权限:
app.UseAuthorization(); // 全局路由默认要求认证 app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}") .RequireAuthorization(); // 单独开放登录页的匿名访问 app.MapControllerRoute( name: "login", pattern: "Account/Login") .AllowAnonymous();
方式二:控制器Action标记
如果登录页对应AccountController的Login方法,直接给Action添加[AllowAnonymous]特性:
public class AccountController : Controller { [AllowAnonymous] public IActionResult Login() { return View(); } }
3. 在自定义登录页触发Azure AD登录
在你的Login.cshtml页面中添加登录按钮,点击后触发OpenIdConnect的认证流程:
<form asp-action="SignInWithAzureAd" method="post"> <button type="submit">使用企业账号登录</button> </form>
然后在AccountController中添加对应的Action,显式发起Azure AD认证挑战:
[AllowAnonymous] public IActionResult SignInWithAzureAd() { // 指定跳转回首页,可根据需求修改目标路径 var redirectUrl = Url.Action("Index", "Home"); return Challenge( new AuthenticationProperties { RedirectUri = redirectUrl }, OpenIdConnectDefaults.AuthenticationScheme); }
关键注意点
- 不要重复调用
AddAuthentication,后执行的配置会覆盖之前的默认认证方案。 - 必须通过
Challenge方法指定使用OpenIdConnect方案,才能触发跳转到Azure AD的登录页。 - 自定义登录页必须设置为匿名访问,否则会陷入「未认证→跳登录页→登录页要求认证→跳登录页」的死循环。
内容的提问来源于stack exchange,提问作者RemarkLima
相关产品推荐
相关产品推荐

