ASP.Net Core 2.2应用中Azure AD认证被跳过问题排查求助
问题根源
[Authorize]特性是MVC/Razor Pages框架的过滤器特性,仅能作用于控制器、页面或它们的Action方法上,无法直接生效在UseRouter绑定的自定义委托方法上。你通过routes.MapGet直接绑定的HomeMiddleware和TestMiddleware属于路由端点委托,MVC的授权过滤器管道不会自动处理这类委托的授权逻辑,因此特性完全未起作用。
解决方法
方法一:改用MVC控制器(推荐,符合框架设计)
将中间件逻辑迁移至MVC控制器,利用框架自带的授权过滤器自动处理[Authorize]:
- 创建控制器:
public class HomeController : Controller { [Authorize(Policy = "AzureAD")] public IActionResult Index() { return Content($"control, User: {User.Identity.Name}"); } [Authorize(Policy = "AzureAD")] public IActionResult Test() { return Content("test another test"); } }
- 修改
Startup.Configure方法,替换UseRouter为MVC路由:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { // 其他中间件保持不变... app.UseAuthentication(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); routes.MapRoute( name: "test", template: "test", defaults: new { controller = "Home", action = "Test" }); }); }
方法二:手动在路由委托中应用授权(适合必须用自定义委托的场景)
若需保留UseRouter的方式,需手动调用授权服务检查用户权限,未通过则触发认证挑战:
- 修改中间件方法,注入
IAuthorizationService(需将方法改为非私有,或通过构造函数注入服务):
private readonly IAuthorizationService _authorizationService; // 通过构造函数注入授权服务 public Startup(IConfiguration configuration, IAuthorizationService authorizationService) { Configuration = configuration; _authorizationService = authorizationService; } private async Task HomeMiddleware(HttpContext context) { // 手动检查授权策略 var authorizationResult = await _authorizationService.AuthorizeAsync(context.User, "AzureAD"); if (!authorizationResult.Succeeded) { // 触发Azure AD认证挑战 await context.ChallengeAsync(AzureADDefaults.AuthenticationScheme); return; } await context.Response.WriteAsync($"control, User: {context.User.Identity.Name}"); } private async Task TestMiddleware(HttpContext context) { var authorizationResult = await _authorizationService.AuthorizeAsync(context.User, "AzureAD"); if (!authorizationResult.Succeeded) { await context.ChallengeAsync(AzureADDefaults.AuthenticationScheme); return; } var writer = new HttpResponseStreamWriter(context.Response.Body, Encoding.UTF8); await writer.WriteAsync("test"); await writer.FlushAsync(); await writer.WriteAsync("another test"); await writer.FlushAsync(); }
额外注意事项
- 你的
CookiePolicyOptions中CheckConsentNeeded = true,意味着用户必须同意Cookie政策才会保存认证Cookie,开发环境可暂时设为false测试,避免因Cookie未保存导致认证后用户信息为空。 - 确认
app.UseAuthentication()在app.UseRouter()之前,这是认证中间件生效的前提,当前你已配置正确。
内容的提问来源于stack exchange,提问作者Narv0007
相关产品推荐
相关产品推荐

