在Docker集群中运行Identity Server的多个实例

DaI*_*mTo 5 docker .net-core identityserver4

我基本上有一个.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(字符串序列化令牌)

我能够算出这是因为密钥是在身份服务器的所有实例上生成的,而不仅仅是生成的一个密钥,并且它们都使用了该密钥。

我添加了以下代码。

services.AddDataProtection()
            .PersistKeysToFileSystem(new DirectoryInfo(settingsSetup.Settings.PersistKeysDirectory))
            .SetDefaultKeyLifetime(TimeSpan.FromDays(90))
            .SetApplicationName($"Awesome-IdentityServer-{_env.EnvironmentName}"); 
Run Code Online (Sandbox Code Playgroud)

基本上告诉身份服务器将密钥存储在哪里。我按照此处找到的说明在Docker容器中托管时持久化密钥,因此我有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节点中运行Identity Server的多个实例吗?

现在具有加密功能。

services.AddDataProtection()
            .PersistKeysToFileSystem(new DirectoryInfo(settingsSetup.Settings.PersistKeysDirectory))
            .SetDefaultKeyLifetime(TimeSpan.FromDays(90))
            .ProtectKeysWithCertificate(LoadCertificate())
            .SetApplicationName($"Awesome-IdentityServer-{_env.EnvironmentName}");
Run Code Online (Sandbox Code Playgroud)

身份服务器在日志中响应以下错误。

未配置XML加密器。密钥{2e0f629c-9dca-44fa-922e-5c5613bd27c8}可以以未加密形式持久存储。

显示该错误给用户

CryptographicException:无法检索解密密钥。System.Security.Cryptography.Xml.EncryptedXml.GetDecryptionKey(EncryptedData加密的数据,字符串对称的AlgorithmUri)

在ASP.NET Core中使用Docker进行身份验证还提到这应该可以工作。

我最初认为这是Identity Server 4的问题,因为他们的文档指出它是无状态的。与他们来回交流后,我在GitHub上发布了一个有状态或无状态的问题,我倾向于认为这更多是docker问题,而不是Identity Server问题。

Sco*_*ady 4

我在客户中看到的常见问题是他们AddDataProtection之前已经注册过AddIdentityServer

AddIdentityServer还会AddDataProtection使用默认设置进行调用,不幸的是,这将覆盖您之前进行的任何注册。

答案很简短:您需要在方法中添加AddDataProtection后缀。AddIdentityServerConfigureServices