JWT授权验证失败:Base64UrlEncoder.Decode方法缺失导致头部无法解码的问题求助
我正在开发API的JWT授权模块,目前遇到了一个棘手的问题——根据抛出的异常栈信息,JWT的头部无法被正常解码。
我收到的具体异常信息如下:
[Authentication failed]
[1º] Method not found: 'Void Microsoft.IdentityModel.Tokens.Base64UrlEncoder.Decode(System.ReadOnlySpan1<Char>, System.Span1)'.
[2º] IDX14102: Unable to decode the header '[PII of type 'Microsoft.IdentityModel.Logging.SecurityArtifact' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]' as Base64Url encoded string.
我已经反复检查过请求的正确性(请求头里确实传递了Authorization: Bearer <token>),也核对了当前使用的NuGet包版本,但始终找不到这个解码方法的替代方案,也不清楚该如何正确修复头部解码的逻辑,希望能得到大家的帮助。
以下是我生成JWT Token的服务代码:
using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using Vestis.Configurations; namespace Vestis.Services; public class JwtService { private readonly JwtSettings _jwtSettings; public JwtService(JwtSettings jwtSettings) { _jwtSettings = jwtSettings; } public string GenerateToken(string userId, string userEmail) { var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecretKey)); var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var claims = new List<Claim> { new Claim(JwtRegisteredClaimNames.Sub, userId), new Claim(JwtRegisteredClaimNames.Email, userEmail), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) }; var token = new JwtSecurityToken( issuer: _jwtSettings.Issuer, audience: _jwtSettings.Audience, claims: claims, expires: DateTime.UtcNow.AddMinutes(_jwtSettings.ExpirationInMinutes), signingCredentials: credentials ); var tokenString = new JwtSecurityTokenHandler().WriteToken(token); // For debugging purposes Console.WriteLine($"Generated JWT Token:\n{tokenString}"); return tokenString; } }
这是我在Program.cs中配置JWT验证的代码:
void ConfigureJWT() { var jwtSettings = new JwtSettings(); builder.Configuration.GetSection("JwtSettings").Bind(jwtSettings); builder.Services.AddSingleton(jwtSettings); var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.SecretKey)); builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = jwtSettings.Issuer, ValidAudience = jwtSettings.Audience, IssuerSigningKey = key }; options.Events = new JwtBearerEvents { OnAuthenticationFailed = context => { Console.WriteLine("[Authentication failed]\n" + PrintExceptionStack(context.Exception,out _)); return Task.CompletedTask; }, OnTokenValidated = context => { Console.WriteLine("[Token validated]\n" + context.SecurityToken); return Task.CompletedTask; } }; }); builder.Services.AddAuthorization(); }
当前使用的NuGet包版本如下(所有包均为最新可用版本,注意Microsoft.IdentityModel.Tokens比其他Microsoft.AspNetCore相关包低一个大版本,但这是该包的最新稳定版):
<ItemGroup> <PackageReference Include="Humanizer" Version="2.14.1" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.2" /> <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.2"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.4.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="7.2.0" /> </ItemGroup>
备注:内容来源于stack exchange,提问作者Jônathas Leandro

