You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 3.1中授权失败(403)如何重定向至自定义错误页

解决ASP.NET Core授权失败(403)重定向到自定义错误页的方案

首先咱们得明确:默认的[Authorize(Roles = "Admin")]在授权失败时会返回403状态码,而非自动重定向——这是因为ASP.NET Core严格区分了**未认证(401)和未授权(403)**两种场景。下面给你几个实用的解决办法,按需选择即可:

方法一:自定义授权处理程序(推荐,灵活性高)

这种方式能精准控制授权失败后的行为,适合需要加入额外逻辑的场景。

  1. 创建自定义授权要求处理类:
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;
    }
}
  1. 在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>();
  1. 替换控制器上的授权标签为自定义策略:
[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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:03:44