ASP.NET Core 8与Duende Identity Server认证失败问题排查求助
排查Duende Identity Server "Unprotect ticket failed" 问题的步骤
1. 确认数据保护密钥共享配置
三个项目必须使用完全一致的数据保护密钥,因为Cookie和认证票据的加密解密依赖这套密钥。本地开发时,默认每个项目会生成独立的密钥存储,导致跨项目无法解密票据。
在所有项目的Program.cs中添加统一的数据保护配置:
builder.Services.AddDataProtection() .PersistKeysToFileSystem(new DirectoryInfo(@"C:\YourSharedKeyFolder")) .SetApplicationName("YourUnifiedAppName");
- 确保所有项目指向同一个本地密钥目录(目录需提前创建)
SetApplicationName的参数必须完全相同,保证密钥上下文一致
2. 核对Cookie认证配置一致性
检查WebServer和AuthorisationServer的Cookie认证配置,重点确认以下字段:
AuthenticationScheme的名称是否匹配Cookie.Name是否一致(比如.AspNetCore.Identity.Application)- 确保两者使用同一个数据保护提供者处理票据
示例AuthorisationServer的Cookie配置:
builder.Services.AddAuthentication() .AddCookie("Identity.Application", options => { options.Cookie.Name = ".AspNetCore.Identity.Application"; options.Cookie.SameSite = SameSiteMode.Lax; options.Cookie.SecurePolicy = CookieSecurePolicy.Always; });
WebServer的OpenIdConnect配置中,要指定对应的Cookie scheme:
builder.Services.AddAuthentication(options => { options.DefaultScheme = "Cookies"; options.DefaultChallengeScheme = "oidc"; }) .AddCookie("Cookies") .AddOpenIdConnect("oidc", options => { options.Authority = "https://localhost:5001"; options.ClientId = "web-server-client"; options.ClientSecret = "your-client-secret"; options.ResponseType = "code"; options.SaveTokens = true; options.Scope.Add("openid"); options.Scope.Add("profile"); options.Scope.Add("your-api-scope"); });
3. 验证JWT密钥匹配(针对APIServer)
APIServer使用JWTBearer认证时,必须确保验证密钥与AuthorisationServer的签发密钥一致:
- 如果使用对称密钥:在APIServer的JWT配置中手动指定相同的密钥
- 如果使用非对称密钥:确保APIServer能通过授权服务器的
/.well-known/openid-configuration端点获取到公钥
示例APIServer的JWT配置:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.Authority = "https://localhost:5001"; options.Audience = "your-api-resource"; // 对称密钥场景下需添加以下配置 // options.TokenValidationParameters = new TokenValidationParameters // { // ValidateIssuerSigningKey = true, // IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your-shared-symmetric-key")) // }; });
4. 检查客户端注册配置
确认AuthorisationServer中注册的WebServer客户端配置无错误:
ClientId、ClientSecret必须与WebServer的OpenIdConnect配置完全匹配RedirectUris、PostLogoutRedirectUris要准确对应WebServer的回调地址(比如https://localhost:5002/signin-oidc)AllowedGrantTypes需设置为GrantTypes.Code(符合你的场景)AllowedScopes要包含openid、profile以及你需要的API范围
示例客户端注册代码:
new Client { ClientId = "web-server-client", ClientName = "Web Server Client", ClientSecrets = { new Secret("your-client-secret".Sha256()) }, AllowedGrantTypes = GrantTypes.Code, RedirectUris = { "https://localhost:5002/signin-oidc" }, PostLogoutRedirectUris = { "https://localhost:5002/signout-callback-oidc" }, AllowedScopes = { "openid", "profile", "your-api-scope" }, AllowOfflineAccess = true }
5. 确保HTTPS配置正确
所有项目必须启用HTTPS:
- 检查每个项目的
launchSettings.json,确认applicationUrl使用HTTPS地址(比如https://localhost:5001) - Cookie的
SecurePolicy设置为CookieSecurePolicy.Always,确保只有HTTPS请求才会携带Cookie
6. 清除浏览器缓存与Cookie
残留的错误认证票据可能导致解密失败,尝试:
- 清除浏览器中对应localhost域名下的所有Cookie
- 使用无痕模式重新测试认证流程
内容的提问来源于stack exchange,提问作者TechQuestion
相关产品推荐
相关产品推荐

