【发布时间】:2020-03-20 11:25:18
【问题描述】:
我有一个 .net core 2.0 应用程序,基本上是身份服务器 4。当我只有一个实例时,它运行得很好。但是,如果我尝试运行多个身份服务器实例,我就会开始遇到问题。
第一期
处理请求时发生未处理的异常。 CryptographicException:在密钥环中找不到密钥 {ec55dd66-7caf-4423-9dd6-74768e80675d}。 Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, bool allowOperationsOnRevokedKeys, out UnprotectStatus status)
InvalidOperationException:无法解密防伪令牌。 Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryTokenSerializer.Deserialize(string serializedToken)
我能够确定这是因为密钥是在身份服务器的所有实例上生成的,而不是只生成一个密钥并且他们都使用了它。
我添加了以下代码。
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(settingsSetup.Settings.PersistKeysDirectory))
.SetDefaultKeyLifetime(TimeSpan.FromDays(90))
.SetApplicationName($"Awesome-IdentityServer-{_env.EnvironmentName}");
这基本上告诉身份服务器将密钥存储在哪里。我按照这里找到的说明Persisting keys when hosting in a Docker container 所以我有A folder that's a Docker volume that persists beyond the container's lifetime, such as a shared volume or a host-mounted volume.
不幸的是,这没有奏效,我现在收到以下错误
“idsrv 未通过身份验证。失败消息:取消保护票证失败”
我认为这意味着密钥需要以某种方式加密。
什么是Unprotect ticket failed,我该如何解决?我可以在 docker 节点中运行多个身份服务器实例吗?
现在有了加密功能。
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(settingsSetup.Settings.PersistKeysDirectory))
.SetDefaultKeyLifetime(TimeSpan.FromDays(90))
.ProtectKeysWithCertificate(LoadCertificate())
.SetApplicationName($"Awesome-IdentityServer-{_env.EnvironmentName}");
身份服务器在日志中响应以下错误。
未配置 XML 加密器。密钥 {2e0f629c-9dca-44fa-922e-5c5613bd27c8} 可能会以未加密的形式保存到存储中。
向用户显示此错误
CryptographicException:无法检索解密密钥。 System.Security.Cryptography.Xml.EncryptedXml.GetDecryptionKey(EncryptedData encryptedData, string symmetricAlgorithmUri)
Authentication with Docker in ASP.NET Core 还提到这应该可以工作。
我最初认为这是 Identity Server 4 的问题,因为他们的文档表明它是无状态的。在与他们来来回回之后,我在 GitHub Stateless or not Stateless 上发布了一个问题,我倾向于认为这更像是一个 docker 问题,而不是身份服务器问题。
【问题讨论】:
-
感觉就像你必须跳过很多圈才能实现这一点。我们使用多台服务器运行负载平衡设置,并使用共享数据库通过实现 IXmlRepository 接口来存储密钥,它工作正常。如果您也想横向扩展,共享数据库更有意义。
-
这将是我的下一步。它只有一个密钥文件,所以对我来说,把它放在数据库接缝中的目录中是有意义的,但我可能别无选择。 (我没有提到它,但我们也设置了负载平衡,幸运的是,这个马戏团的一部分不是我的工作)
-
这看起来像是正确的文档,可以继续使用:)
-
顺便说一句,密钥不必加密即可工作。你可以先不加密调试:)
标签: docker .net-core identityserver4