如何自定义OpenIddict无效Token响应以添加JSON响应体?
问题描述
当向API发送携带无效访问令牌的请求时,当前得到的响应如下:
Base Address: https://localhost:54701/ Token Expired: True IsSuccessStatusCode: False Status: Unauthorized StatusCode: 401 WwwAuthenticate: Bearer error="invalid_token", error_description="The specified token is invalid.", error_uri="https://documentation.openiddict.com/errors/ID2004" ReasonPhrase: Unauthorized ContentType: ContentLength: 0 Content:
希望自定义该响应,在响应体中返回指定JSON内容:
{ "Message": "Authorization has been denied for this request." }
最终期望的响应形式为:
Base Address: https://localhost:54701/ Token Expired: True IsSuccessStatusCode: False Status: Unauthorized StatusCode: 401 WwwAuthenticate: Bearer error="invalid_token", error_description="The specified token is invalid.", error_uri="https://documentation.openiddict.com/errors/ID2004" ReasonPhrase: Unauthorized ContentType: application/json; charset=utf-8 ContentLength: 61 Content: { "Message": "Authorization has been denied for this request." }
请问是否存在可挂钩的事件来实现此自定义需求?
解决方案
当然可以通过挂钩认证流程中的事件来实现这个自定义需求,以下是两种常用的实现方式:
1. 利用JWT Bearer认证的OnChallenge事件
如果你的API基于JWT Bearer认证(结合OpenIddict),可以在配置认证服务时,通过JwtBearerOptions的Events属性自定义挑战响应:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.Events = new JwtBearerEvents { OnChallenge = context => { // 阻止默认的挑战响应逻辑 context.HandleResponse(); // 设置响应状态码与内容类型 context.Response.StatusCode = StatusCodes.Status401Unauthorized; context.Response.ContentType = "application/json; charset=utf-8"; // 写入自定义JSON响应 var response = new { Message = "Authorization has been denied for this request." }; return context.Response.WriteAsJsonAsync(response); } }; });
2. 利用OpenIddict的认证事件
如果直接使用OpenIddict的验证中间件,可以通过AddEventHandler挂钩ProcessChallengeContext事件来定制响应:
services.AddOpenIddict() .AddValidation(options => { options.AddEventHandler<ProcessChallengeContext>(builder => { builder.UseInlineHandler(context => { // 设置内容类型并写入自定义响应体 context.Response.ContentType = "application/json; charset=utf-8"; var response = new { Message = "Authorization has been denied for this request." }; return context.Response.WriteAsJsonAsync(response); }); }); });
注意事项
- 上述两种方式都不会移除默认的
Www-Authenticate响应头,完全符合你期望的最终响应格式。 - 调用
context.HandleResponse()会阻止框架生成默认的空响应体,确保你的自定义内容能正常返回。
内容的提问来源于stack exchange,提问作者Adrian Wright
相关产品推荐
相关产品推荐

