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

如何在ASP.NET Core中用AuthorizationHandler处理未授权API调用并返回401

解决ASP.NET Core 8 API授权失败返回302而非401/403的问题

问题核心是ASP.NET Core默认身份验证/授权中间件为MVC场景设计,会自动重定向到登录或AccessDenied页面,而API端点需要返回标准HTTP状态码给Angular客户端。以下是具体解决步骤:

1. 拦截Cookie认证的重定向行为

在配置Cookie认证时,判断请求是否为API请求(通过路径或Accept头),如果是则直接返回对应状态码,而非重定向:

builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
    // 处理未登录的重定向
    options.Events.OnRedirectToLogin = context =>
    {
        if (IsApiRequest(context.Request))
        {
            context.Response.StatusCode = StatusCodes.Status401Unauthorized;
            return Task.CompletedTask;
        }
        context.Response.Redirect(context.RedirectUri);
        return Task.CompletedTask;
    };

    // 处理权限不足的重定向
    options.Events.OnRedirectToAccessDenied = context =>
    {
        if (IsApiRequest(context.Request))
        {
            context.Response.StatusCode = StatusCodes.Status403Forbidden;
            return Task.CompletedTask;
        }
        context.Response.Redirect(context.RedirectUri);
        return Task.CompletedTask;
    };
})
.AddOpenIdConnect(options =>
{
    // 你的OIDC基础配置(Authority、ClientId等)
    options.Authority = "你的OIDC授权地址";
    options.ClientId = "你的客户端ID";
    options.ClientSecret = "你的客户端密钥";
    options.ResponseType = OpenIdConnectResponseType.Code;

    // 拦截OIDC的重定向请求
    options.Events.OnRedirectToIdentityProvider = context =>
    {
        if (IsApiRequest(context.Request))
        {
            context.Response.StatusCode = StatusCodes.Status401Unauthorized;
            context.HandleResponse(); // 终止后续重定向逻辑
        }
        return Task.CompletedTask;
    };
});

// 辅助方法:判断是否为API请求
bool IsApiRequest(HttpRequest request)
{
    return request.Path.StartsWithSegments("/api") || 
           request.Headers.Accept.Contains("application/json");
}

2. 自定义授权失败处理器

如果API使用了自定义AuthorizationHandler,可以添加全局授权失败处理器,确保API场景下返回正确状态码:

实现授权失败处理器

public class ApiAuthorizationFailureHandler : IAuthorizationFailureHandler
{
    public Task HandleAsync(AuthorizationHandlerContext context)
    {
        var httpContext = context.Resource as HttpContext;
        if (httpContext != null && IsApiRequest(httpContext.Request))
        {
            httpContext.Response.StatusCode = context.User.Identity.IsAuthenticated
                ? StatusCodes.Status403Forbidden
                : StatusCodes.Status401Unauthorized;
        }
        return Task.CompletedTask;
    }

    private bool IsApiRequest(HttpRequest request)
    {
        return request.Path.StartsWithSegments("/api") || 
               request.Headers.Accept.Contains("application/json");
    }
}

注册处理器

builder.Services.AddScoped<IAuthorizationFailureHandler, ApiAuthorizationFailureHandler>();

3. 配置API专属授权策略

在授权配置中,为API端点指定专属策略,确保使用自定义失败处理器:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("ApiPolicy", policy =>
    {
        policy.RequireAuthenticatedUser();
        policy.AddRequirements(new YourCustomRequirement()); // 你的自定义权限要求
        policy.FailureHandler = new ApiAuthorizationFailureHandler();
    });
});

然后在极简API端点上应用该策略:

app.MapGet("/api/your-endpoint", () => Results.Ok("内容"))
   .RequireAuthorization("ApiPolicy");

关键说明

  • 区分API和MVC请求:通过路径前缀(如/api)或Accept头判断,保证MVC页面仍能正常重定向到登录/拒绝页面,API则返回状态码。
  • 终止重定向逻辑:在OIDC事件中调用context.HandleResponse()可以阻止后续的重定向流程,直接返回状态码。

内容的提问来源于stack exchange,提问作者Andrew HB

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 07:55:01