为带[Authorize]属性的ASP.NET Core接口返回自定义异常方法
自定义ASP.NET Core授权失败的401响应体
要给未授权访问返回带内容的自定义响应,你可以用以下几种方式实现:
方法1:JWT认证场景下配置挑战事件
如果你的项目基于JWT认证,直接在AddJwtBearer的配置中添加OnChallenge事件,覆盖默认的空响应:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = builder.Configuration["Jwt:Issuer"], ValidAudience = builder.Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])) }; // 自定义未授权响应 options.Events = new JwtBearerEvents { OnChallenge = async context => { // 跳过默认的响应处理逻辑 context.HandleResponse(); // 构造自定义响应内容 var errorResponse = new { StatusCode = StatusCodes.Status401Unauthorized, Message = "未授权访问,请提供有效的认证令牌", Detail = "请求缺少合法的Authorization头或令牌已失效" }; // 设置响应类型和状态码 context.Response.ContentType = "application/json"; context.Response.StatusCode = StatusCodes.Status401Unauthorized; // 写入响应体 await context.Response.WriteAsync(JsonSerializer.Serialize(errorResponse)); } }; });
方法2:自定义授权过滤器
如果需要更灵活的授权逻辑,或者不依赖JWT,可以自定义一个授权过滤器:
public class CustomAuthorizeFilter : IAuthorizationFilter { public void OnAuthorization(AuthorizationFilterContext context) { // 判断用户是否未通过认证 if (!context.HttpContext.User.Identity.IsAuthenticated) { var customResponse = new { Code = 401, Message = "您没有权限访问此接口,请先完成认证", Timestamp = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss") }; // 返回自定义JSON响应 context.Result = new JsonResult(customResponse) { StatusCode = StatusCodes.Status401Unauthorized }; } } }
注册过滤器
- 控制器级别:在目标控制器或接口上添加过滤器特性
[ApiController] [Route("[controller]")] [TypeFilter(typeof(CustomAuthorizeFilter))] public class WeatherForecastController : ControllerBase { // ... 控制器代码 }
- 全局级别:在Program.cs中注册,对所有接口生效
builder.Services.AddControllers(options => { options.Filters.Add<CustomAuthorizeFilter>(); });
方法3:用中间件全局拦截401响应
这种方式可以统一处理所有返回401且响应体为空的情况,无需修改控制器或认证配置:
public class CustomUnauthorizedMiddleware { private readonly RequestDelegate _next; public CustomUnauthorizedMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context) { // 先执行后续中间件 await _next(context); // 检查是否是401且响应体为空 if (context.Response.StatusCode == StatusCodes.Status401Unauthorized && context.Response.ContentLength == 0) { context.Response.ContentType = "application/json"; var errorResponse = new { Status = "error", Message = "未授权访问", StatusCode = 401 }; await context.Response.WriteAsync(JsonSerializer.Serialize(errorResponse)); } } }
注册中间件
在Program.cs中,将中间件放在UseAuthentication和UseAuthorization之后:
app.UseAuthentication(); app.UseAuthorization(); // 添加自定义未授权中间件 app.UseMiddleware<CustomUnauthorizedMiddleware>(); app.MapControllers();
内容的提问来源于stack exchange,提问作者yonan2236
相关产品推荐
相关产品推荐

