首页 新闻 会员 周边 捐助

ASP.NET Core 中 PAT 验证问题:"IDX14100: JWT is not well formed, there are no dots (.)"

0
悬赏园豆:30 [已解决问题] 解决于 2025-05-04 13:10

用的是 ASP.NET Core 9.0 与 Cnblogs.IdentityServer4 4.3.0,带 PAT(Personal Access Token) 请问 api 使出现下面的错误:

2025-05-04 11:11:34.755 +08:00 [INF] Failed to validate the token.
Microsoft.IdentityModel.Tokens.SecurityTokenMalformedException: IDX14100: JWT is not well formed, there are no dots (.).
The token needs to be in JWS or JWE Compact Serialization Format. (JWS): 'EncodedHeader.EncodedPayload.EncodedSignature'. (JWE): 'EncodedProtectedHeader.EncodedEncryptedKey.EncodedInitializationVector.EncodedCiphertext.EncodedAuthenticationTag'.
   at Microsoft.IdentityModel.JsonWebTokens.JsonWebToken.ReadToken(ReadOnlyMemory`1 encodedTokenMemory)
   at Microsoft.IdentityModel.JsonWebTokens.JsonWebToken..ctor(String jwtEncodedString)
   at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ReadToken(String token, TokenValidationParameters validationParameters)

对应的 Authentication 配置代码:

services.AddAuthentication("token")
    // PAT or reference token
    .AddOAuth2Introspection("introspection", options =>
    {
        options.Authority = webApiOptions.Authority;
        options.ClientId = webApiOptions.ApiName;
        options.ClientSecret = webApiOptions.ApiSecret;
        options.EnableCaching = true;
        options.DiscoveryPolicy.ValidateIssuerName = false;
        options.DiscoveryPolicy.RequireHttps = false;
    });

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer("Bearer", options =>
    {
        options.Authority = webApiOptions.Authority;
        options.Audience = webApiOptions.ApiName;
        options.RequireHttpsMetadata = webApiOptions.RequireHttpsMetadata;
    });
dudu的主页 dudu | 高人七级 | 园豆:24728
提问于:2025-05-04 11:22
< >
分享
最佳答案
0

带 PAT 发请求时,也用的是 Bearer 验证请求头,也会走 AddJwtBearer("Bearer") 对应的 JwtBearerHandler

Authorization: Bearer <token>

解决这个问题,需要通过 ForwardDefaultSelector 转发请求到 introspection scheme

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer("Bearer", options =>
    {
        options.Authority = webApiOptions.Authority;
        options.Audience = webApiOptions.ApiName;
        options.RequireHttpsMetadata = webApiOptions.RequireHttpsMetadata;
        options.ForwardDefaultSelector = Selector.ForwardReferenceToken("introspection");
    });

ForwardReferenceToken 对应的实现代码

// Copy from IdentityModel.AspNetCore.AccessTokenValidation
public static class Selector
{     
    public static Func<HttpContext, string> ForwardReferenceToken(string introspectionScheme = "Introspection")
    {
        return Select;
        string Select(HttpContext context)
        {
            var (text, text2) = GetSchemeAndCredential(context);
            if (text.Equals("Bearer", StringComparison.OrdinalIgnoreCase) && !text2.Contains("."))
            {
                return introspectionScheme;
            }

            return null;
        }
    }

    public static (string, string) GetSchemeAndCredential(HttpContext context)
    {
        string text = context.Request.Headers["Authorization"].FirstOrDefault();
        if (string.IsNullOrEmpty(text))
        {
            return (string.Empty, string.Empty);
        }

        string[] array = text.Split(' ', StringSplitOptions.RemoveEmptyEntries);
        if (array.Length != 2)
        {
            return (string.Empty, string.Empty);
        }

        return (array[0], array[1]);
    }
}
dudu | 高人七级 |园豆:24728 | 2025-05-04 13:06
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册