ASP.NET Core 6中AuthorizationHandler重定向时如何避免执行控制器代码?
解决.NET Core 6 MVC自定义授权失败时的重定向问题
核心问题分析
你当前的矛盾点在于:
- 调用
context.Succeed(requirement)会让授权管道判定为"通过",导致控制器Action代码先执行,再执行重定向,存在安全风险 - 调用
context.Fail()会触发框架默认的403响应,无法自定义重定向
正确的解决思路是分离授权逻辑与重定向逻辑:授权Handler仅负责判断权限并标记结果,重定向逻辑交给专门的授权结果处理器来处理,这样既能阻止Action执行,又能实现自定义跳转。
步骤1:修正自定义AuthorizationHandler
修改Handler,仅专注于权限校验,授权失败时只标记context.Fail(),不直接操作Response:
public class ItAdminAuthorizationHandler : AuthorizationHandler<ItAdminRequirement> { private readonly PulseContext _context; public ItAdminAuthorizationHandler(PulseContext context) { _context = context; } protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ItAdminRequirement requirement) { if (context.User == null) { context.Fail(); return Task.CompletedTask; } var userName = context.User.Identity.Name; // 仅校验权限,不处理重定向 if (_context.Users.Any(u => u.Username.Equals(userName) && u.Active && u.UserRole.Name == "IT Admin")) { context.Succeed(requirement); } else { context.Fail(); // 标记授权失败 } return Task.CompletedTask; } }
步骤2:自定义授权结果处理器
创建实现IAuthorizationMiddlewareResultHandler的类,拦截授权失败结果并执行重定向:
public class CustomAuthorizationResultHandler : IAuthorizationMiddlewareResultHandler { // 保留默认处理器处理其他授权场景 private readonly AuthorizationMiddlewareResultHandler _defaultHandler = new(); public async Task HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) { // 拦截授权失败(Forbidden)的情况 if (authorizeResult.Forbidden) { // 重定向到无权限页面 context.Response.Redirect("/Home/NoAccess"); return; } // 其他授权结果(如成功、未认证)交给默认处理器处理 await _defaultHandler.HandleAsync(next, context, policy, authorizeResult); } }
步骤3:注册自定义处理器到DI容器
在Program.cs中替换默认的授权结果处理器,并确保授权策略和Handler已正确注册:
// 注册自定义授权结果处理器 builder.Services.AddSingleton<IAuthorizationMiddlewareResultHandler, CustomAuthorizationResultHandler>(); // 配置授权策略 builder.Services.AddAuthorization(options => { options.AddPolicy("ItAdmin", policy => policy.Requirements.Add(new ItAdminRequirement())); }); // 注册自定义AuthorizationHandler builder.Services.AddScoped<IAuthorizationHandler, ItAdminAuthorizationHandler>();
额外注意事项
确保无权限页面允许匿名访问,避免循环重定向:
[AllowAnonymous] public IActionResult NoAccess() { return View(); }
内容的提问来源于stack exchange,提问作者Brent Kilboy
相关产品推荐
相关产品推荐

