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

配置多个JwtBearer认证提供者时Postman出现解析错误

问题描述

尝试添加两个JwtBearer认证提供者(Auth0和自定义提供者),使用Postman测试时持续遇到**"Parse Error: Invalid character in chunk size"**错误。

参考相关资料实现的代码如下:

认证服务配置

builder.Services
    .AddAuthentication()
    .AddJwtBearer("Auth0", options =>
    {
        options.Authority = builder.Configuration["Auth0:Domain"];
        options.Audience = builder.Configuration["Auth0:Audience"];
        options.Events = new JwtBearerEvents
        {
            OnAuthenticationFailed = context =>
            {
                context.Response.OnStarting(async () =>
                {
                    await context.Response.WriteAsync("You are not authorized to be here. Go away.");
                });
                return Task.CompletedTask;
            },
            OnForbidden = context =>
            {
                context.Response.OnStarting(async () =>
                {
                    await context.Response.WriteAsync("You are a valid user, but Forbidden to use this resource");
                });
                return Task.CompletedTask;
            }
        };
        options.TokenValidationParameters = new TokenValidationParameters
        {
            NameClaimType = ClaimTypes.NameIdentifier
        };
    })
    .AddJwtBearer("Custom", options =>
    {
        options.Events = new JwtBearerEvents
        {
            OnAuthenticationFailed = context =>
            {
                context.Response.OnStarting(async () =>
                {
                    await context.Response.WriteAsync("You are not authorized to be here. Go Away.");
                });
                return Task.CompletedTask;
            }
        };
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = false,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = builder.Configuration["JwtIssuer"],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["JwtSecretKey"])),
            ClockSkew = TimeSpan.Zero
        };
    });

授权策略配置

builder.Services.AddAuthorization(options =>
{
    options.DefaultPolicy = new AuthorizationPolicyBuilder()
     .RequireAuthenticatedUser()
     .AddAuthenticationSchemes("Custom", "Auth0")
     .Build();
});

测试自定义JWT时,令牌验证通过且能进入控制器,仓储也能从数据库返回设备,但Postman会出现上述错误。经调试发现,若不设置builder.Services.AddAuthorization()中的默认策略,一切正常,响应可正常返回。

请问是否遗漏了什么?是否不需要指定默认策略?


解决方法

这个错误的核心原因是在OnAuthenticationFailed和OnForbidden事件中直接写入响应内容,但未正确终止认证流程。当指定多个认证方案时,认证中间件会依次尝试每个方案——即使第一个方案验证成功,后续方案的事件仍可能被触发,导致多次写入响应,破坏HTTP响应的分块编码格式,最终引发Postman的解析错误。

具体修复步骤:

  1. 在事件处理中终止流程
    在OnAuthenticationFailed和OnForbidden事件中,设置响应状态码和内容后,调用context.HandleResponse()来终止后续的认证/授权流程,避免多次修改响应。修改后的事件处理示例:

    // Auth0方案的事件修改
    OnAuthenticationFailed = context =>
    {
        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
        context.Response.ContentType = "text/plain";
        context.Response.OnStarting(async () =>
        {
            await context.Response.WriteAsync("You are not authorized to be here. Go away.");
        });
        context.HandleResponse(); // 终止后续流程,防止其他方案继续处理
        return Task.CompletedTask;
    },
    OnForbidden = context =>
    {
        context.Response.StatusCode = StatusCodes.Status403Forbidden;
        context.Response.ContentType = "text/plain";
        context.Response.OnStarting(async () =>
        {
            await context.Response.WriteAsync("You are a valid user, but Forbidden to use this resource");
        });
        context.HandleResponse(); // 终止后续流程
        return Task.CompletedTask;
    }
    
    // Custom方案的事件修改
    OnAuthenticationFailed = context =>
    {
        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
        context.Response.ContentType = "text/plain";
        context.Response.OnStarting(async () =>
        {
            await context.Response.WriteAsync("You are not authorized to be here. Go Away.");
        });
        context.HandleResponse(); // 终止后续流程
        return Task.CompletedTask;
    }
    
  2. 关于默认策略的说明
    指定默认策略是正确的做法,它确保所有需要授权的端点都会依次尝试Custom和Auth0两个认证方案。问题并不出在策略本身,而是事件处理中未正确终止流程导致响应格式被破坏。

额外注意事项:

  • 写入响应时务必设置ContentType,避免Postman因无法识别响应格式而报错。
  • 确保每个认证方案的事件处理逻辑不会产生冲突的响应内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 06:31:02