升级System.IdentityModel.Tokens相关包至7.0.0后JWT验证失败求助
问题背景
在网站登录功能中使用JWT认证,升级Microsoft.IdentityModel.Tokens和System.IdentityModel.Tokens.Jwt至7.0.0版本后,出现以下错误:
IDX20803: Unable to obtain configuration from: 'https://accounts.example.com/realms/SampleRealm/.well-known/openid-configuration'.
相关配置代码如下:
public static void AddIdentity(IServiceCollection services) { services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(jwtOptions => { jwtOptions.Authority = @$"{ApiConfig.GetSetting("KeycloakUrl").Trim('/')}/realms/{ApiConfig.GetSetting("Realm")}"; jwtOptions.Audience = "account"; jwtOptions.Events = new JwtBearerEvents() { OnAuthenticationFailed = c => { c.NoResult(); Logger.LogException(c.Exception); c.Response.StatusCode = 500; c.Response.ContentType = "text/plain"; if (ApiConfig.IsDeveloping) { return c.Response.WriteAsync(c.Exception.ToString()); } return c.Response.WriteAsync("An error occured processing your authentication."); }, OnTokenValidated = c => { if (c.Principal.IsInRole("SuperAdmin")) { c.HttpContext.Items["IsSuperAdmin"] = true; } return System.Threading.Tasks.Task.CompletedTask; } }; }); services.AddAuthorization(options => { if (IsSecurityEnabled()) { if (ApiConfig.Role.IsSomething()) { options.AddPolicy("HasRole", policy => policy.RequireRole(ApiConfig.Role)); } else { options.AddPolicy("HasRole", policy => policy.RequireAssertion(x => x.User.Identity.IsAuthenticated)); } } else { options.AddPolicy("HasRole", policy => policy.RequireAssertion(x => true)); } }); }
解决方案
验证OIDC端点可达性
手动访问错误信息中的/.well-known/openid-configurationURL,确认能否正常返回JSON格式的配置内容。如果无法访问,排查Keycloak服务是否正常运行、域名解析是否正确、网络防火墙/代理是否阻止了请求。检查TLS/SSL兼容性
7.0.0版本的JWT库默认可能禁用了旧版TLS协议(如TLS 1.0/1.1),需确保Keycloak服务器配置支持TLS 1.2及以上版本。如果使用自签名证书,需确保API服务信任该证书(开发环境可临时跳过证书验证,生产环境必须配置正确的证书信任链)。配置自定义HttpClientHandler
在AddJwtBearer中添加自定义的HttpHandler,处理证书验证或代理问题:.AddJwtBearer(jwtOptions => { // 原有配置... jwtOptions.BackchannelHttpHandler = new HttpClientHandler { // 开发环境临时禁用证书验证(生产环境请勿使用) ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => ApiConfig.IsDeveloping ? true : sslPolicyErrors == SslPolicyErrors.None, // 若需通过代理访问Keycloak,添加以下配置 // Proxy = new WebProxy("http://your-proxy-address:port"), // UseProxy = true }; });获取详细异常信息
修改OnAuthenticationFailed事件,输出内部异常细节,定位真正的错误原因:OnAuthenticationFailed = c => { c.NoResult(); Logger.LogException(c.Exception); c.Response.StatusCode = 500; c.Response.ContentType = "text/plain"; var errorDetails = ApiConfig.IsDeveloping ? $"{c.Exception}\n\nInner Exception: {c.Exception.InnerException}" : "An error occurred processing your authentication."; return c.Response.WriteAsync(errorDetails); }确认Authority URL格式
检查拼接后的AuthorityURL是否正确,确保没有多余的斜杠或拼写错误。例如,正确格式应为https://accounts.example.com/realms/SampleRealm,避免尾部斜杠导致的端点拼接错误。查阅版本变更日志
查看官方7.0.0版本的迁移文档,确认是否有OIDC配置获取逻辑的变更,比如默认HttpClient行为调整、端点验证规则变化等,针对性调整配置。
内容的提问来源于stack exchange,提问作者Hasan

