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

如何自定义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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 07:01:07