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

Asp.net Core 6 MVC RSA算法身份验证未授权问题求助

RSA签名JWT授权失败排查及修复

核心问题1:发行方(Issuer)验证不匹配

生成Token时,SecurityTokenDescriptor的Issuer设为空字符串,但验证配置中开启了ValidateIssuer = true且未指定ValidIssuer,导致验证逻辑判定Token无效。

修复方案:

  • 方式一:统一Issuer值,生成和验证时保持一致
    生成Token时设置有效Issuer:
    var descriptor = new Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor
    {
        Issuer = "your-issuer-name", // 例如"IndraUI"
        Claims = payload,
        SigningCredentials = new SigningCredentials(new RsaSecurityKey(rsa), SecurityAlgorithms.RsaSha256) 
        { 
            CryptoProviderFactory = new CryptoProviderFactory { CacheSignatureProviders = false } 
        },
        IssuedAt = System.DateTime.UtcNow,
        Expires = System.DateTime.UtcNow.AddDays(15),
    };
    
    验证配置中同步设置:
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidIssuer = "your-issuer-name",
        // 其他配置...
    };
    
  • 方式二:若不需要验证Issuer,关闭验证开关
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = false,
        // 其他配置...
    };
    

核心问题2:受众(Audience)验证未配置但开启

生成Token时未指定Audience,但验证配置中ValidateAudience = true且未设置ValidAudience,同样会触发验证失败。

修复方案:

  • 方式一:配置Audience并保持一致
    生成Token时添加Audience:
    var descriptor = new Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor
    {
        Audience = "your-audience-name", // 例如"IndraAPI"
        // 其他配置...
    };
    
    验证配置中同步设置:
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidAudience = "your-audience-name",
        // 其他配置...
    };
    
  • 方式二:关闭Audience验证(若业务不需要)
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateAudience = false,
        // 其他配置...
    };
    

问题3:公钥加载逻辑冗余且易出错

手动替换公钥的头尾标记和换行可能因格式问题(比如换行符不一致)导致公钥加载失败,建议使用RSA.ImportFromPem简化加载逻辑:

修复后的公钥加载代码:

builder.Services.AddSingleton<RsaSecurityKey>(provider =>
{    
    string publicKey = System.IO.File.ReadAllText("D:\\wwwroot\\keys\\publickey.crt");
    var rsa = System.Security.Cryptography.RSA.Create();
    rsa.ImportFromPem(publicKey.AsSpan()); // 直接加载PEM格式公钥,无需手动处理Base64
    return new RsaSecurityKey(rsa);
});

问题4:服务实例获取方式不当

在AddJwtBearer中直接调用builder.Services.BuildServiceProvider()会创建新的服务提供者实例,可能导致和后续注入的服务不一致,建议通过options.Events获取服务:

修复后的验证配置代码:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.IncludeErrorDetails = true;

        options.TokenValidationParameters = new TokenValidationParameters
        {
            RequireSignedTokens = true,
            RequireExpirationTime = true, 
            ValidateLifetime = true, 
            ValidateAudience = false, // 先关闭测试,确认签名有效后再开启
            ValidateIssuer = false,   // 先关闭测试,确认签名有效后再开启
        };

        // 通过请求上下文获取正确的RSA密钥实例
        options.Events = new JwtBearerEvents
        {
            OnTokenValidated = context =>
            {
                var rsaKey = context.HttpContext.RequestServices.GetRequiredService<RsaSecurityKey>();
                context.SecurityTokenValidatedContext.TokenValidationParameters.IssuerSigningKey = rsaKey;
                return Task.CompletedTask;
            }
        };
    });

排查建议

先关闭Issuer和Audience验证,测试Token是否能正常通过签名验证,确认签名逻辑没问题后,再逐步开启需要的验证项,缩小排查范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 22:47:53