Identity Server连接始终返回Forbidden错误求助排查
问题现象
在Plesk管理的共享主机上部署了两个服务:
- Skoruba.Duende.IdentityServer.STS.Identity:https://sso.cungthugian.com
- Skoruba.Duende.IdentityServer.Admin:https://iadmin.cungthugian.com
从Admin站点连接Identity Server时持续返回Forbidden错误,且无法获取发现文档https://sso.cungthugian.com/.well-known/openid-configuration。但本地修改Host文件映射后功能完全正常。
SSO服务端错误日志(已翻译):
反序列化令牌时引发异常。
Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException: 无法解密防伪令牌。
---> System.Security.Cryptography.CryptographicException: 密钥 {49a42129-c09b-412e-bee5-df02c7878e2e} 未在密钥环中找到。
在 Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status)
在 Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData)
在 Microsoft.AspNetCore.Antiforgery.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken)
--- 内部异常堆栈跟踪结束 ---
在 Microsoft.AspNetCore.Antiforgery.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken)
在 Microsoft.AspNetCore.Antiforgery.DefaultAntiforgery.GetCookieTokenDoesNotThrow(HttpContext httpContext)
问题根源
共享主机环境中,ASP.NET Core默认的数据保护密钥存储机制无法在多个站点间共享密钥环,且默认的临时存储位置可能会被主机回收或隔离,导致防伪令牌生成和使用时的密钥不匹配,最终解密失败。本地环境改Host后正常,是因为本地开发环境的密钥存储稳定且两个站点共享同一密钥环。
解决方案
1. 统一配置数据保护密钥持久化存储
在SSO和Admin项目的Program.cs中,添加数据保护配置,指定共享的持久化密钥存储目录,并设置相同的应用名称:
builder.Services.AddDataProtection() .PersistKeysToFileSystem(new DirectoryInfo(@"[Plesk主机上的共享目录路径]")) // 替换为实际可访问的共享目录,比如 /var/www/shared-keys 或 D:\Hosting\SharedKeys .SetApplicationName("SkorubaIdentityServerCluster"); // 两个站点必须使用相同的应用名称
需要在Plesk面板中为两个站点配置该目录的读写权限,确保应用程序池身份能访问。
2. 检查Plesk应用程序池配置
- 优先让两个站点使用同一个应用程序池,避免权限隔离导致密钥无法共享。
- 如果必须使用不同池,需确保每个池的身份账户拥有共享密钥目录的读写权限。
3. 清理旧Cookie
部署配置后,要求访问者清除浏览器中与两个站点相关的Cookie(如.AspNetCore.Antiforgery.*、SSO认证Cookie),避免旧的无效令牌干扰新的密钥验证流程。
4. 验证发现文档的访问路径
检查Plesk中SSO站点的URL重写规则,确保.well-known/openid-configuration路径未被拦截或错误重定向。同时确认站点SSL证书配置正确,无HTTPS握手问题导致请求失败。
内容的提问来源于stack exchange,提问作者Hoa Tran

