ASP.NET Core 3.1中授权失败(403)如何重定向至自定义错误页
解决ASP.NET Core授权失败(403)重定向到自定义错误页的方案
首先咱们得明确:默认的[Authorize(Roles = "Admin")]在授权失败时会返回403状态码,而非自动重定向——这是因为ASP.NET Core严格区分了**未认证(401)和未授权(403)**两种场景。下面给你几个实用的解决办法,按需选择即可:
方法一:自定义授权处理程序(推荐,灵活性高)
这种方式能精准控制授权失败后的行为,适合需要加入额外逻辑的场景。
- 创建自定义授权要求处理类:
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using System.Threading.Tasks; public class AdminAuthorizationHandler : AuthorizationHandler<RolesAuthorizationRequirement> { private readonly IHttpContextAccessor _httpContextAccessor; public AdminAuthorizationHandler(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RolesAuthorizationRequirement requirement) { var httpContext = _httpContextAccessor.HttpContext; if (!context.User.IsInRole("Admin")) { // 授权失败,重定向到自定义禁止访问页 httpContext.Response.Redirect("/Error/Forbidden"); context.Succeed(requirement); // 标记为已处理,避免默认逻辑返回403 return Task.CompletedTask; } context.Succeed(requirement); return Task.CompletedTask; } }
- 在
Program.cs(或Startup.cs,取决于你的.NET版本)中注册服务:
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); builder.Services.AddAuthorization(options => { options.AddPolicy("AdminPolicy", policy => policy.Requirements.Add(new RolesAuthorizationRequirement(new[] { "Admin" }))); }); builder.Services.AddSingleton<IAuthorizationHandler, AdminAuthorizationHandler>();
- 替换控制器上的授权标签为自定义策略:
[Authorize(Policy = "AdminPolicy")] public class AdminController : Controller { // 你的控制器业务逻辑 }
方法二:全局中间件捕获403状态码
如果不需要复杂的授权逻辑,只想统一处理所有403响应,这种方式最简洁。
在Program.cs中添加自定义中间件,注意要放在app.UseAuthorization()之后:
app.Use(async (context, next) => { await next(); // 检查响应是否为403禁止访问 if (context.Response.StatusCode == StatusCodes.Status403Forbidden) { // 重定向到自定义错误页 context.Response.Redirect("/Error/Forbidden"); } });
⚠️ 注意:这个中间件会捕获系统中所有的403响应,包括非控制器授权产生的403,如果你只想针对特定控制器的授权失败,方法一更合适。
方法三:配置Cookie认证的AccessDeniedPath(仅适用于Cookie认证场景)
如果你项目用的是Cookie认证,可以直接在认证配置里指定授权失败后的跳转路径,一步到位:
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.AccessDeniedPath = "/Error/Forbidden"; // 其他Cookie认证配置(比如登录路径、过期时间等) });
这种方式最简单,但仅对Cookie认证生效,且是全局统一配置。
最后别忘了创建对应的自定义错误页,比如在Views/Error/Forbidden.cshtml(Razor Pages项目则是Pages/Error/Forbidden.cshtml),写入你需要的错误提示内容即可。
内容的提问来源于stack exchange,提问作者Nabil Dendane
相关产品推荐
相关产品推荐

