gpt4 book ai didi

c# - 扩展 IdentityServer4 服务

转载 作者:可可西里 更新时间:2023-11-01 09:12:44 26 4
gpt4 key购买 nike

我已经关注了 IdentityServer4 quickstarts并且能够使用隐式授权使用本地托管的 IdentityServer 实例验证我的 javascript 网页(几乎与快速入门中提供的相同)。同样,我的 IdentityServer 与上述快速入门中提供的几乎完全相同 - 它只是包含一些自定义用户详细信息。

然后我将我的应用程序(C# .NET Core)移动到一个 docker 容器中,并在 Kubernetes 集群(单个实例)中托管了一个实例,并创建了一个 Kubernetes 服务(一个或多个“真实”服务的外观)让我从集群外部访问身份服务器。我可以修改我的 JavaScript 网页并将其指向我的 Kubernetes 服务,它仍然会很高兴地显示登录页面,而且它似乎按预期工作。

然后,当我将 IdentityServer 扩展到三个实例(所有实例均在单个 Kubernetes 服务后提供服务)时,我开始遇到问题。Kubernetes 服务循环请求每个身份服务器,因此第一个将显示登录页面,但第二个将在我按下登录按钮后尝试处理身份验证。这会导致以下错误:

System.InvalidOperationException: The antiforgery token could not be decrypted. ---> System.Security.Cryptography.CryptographicException: The key {19742e88-9dc6-44a0-9e89-e7b09db83329} was not found in the key ring. at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(Byte[] protectedData, Boolean ignoreRevocationErrors, Boolean& requiresMigration, Boolean& wasRevoked) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData) at Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken) --- End of inner exception stack trace --- ... And lots more......

所以 - 我知道我收到这个错误是因为期望同一个 IdentityServer 应该为它所显示的页面请求提供服务(否则防伪 token 将如何工作,对吗?),但我我试图了解如何在复制环境中完成这项工作。

我不想在不同的 IP/端口上托管多个身份服务器;我正在尝试构建一个 HA 配置,如果一个 IdentityServer 挂掉,调用端点的任何事情都不会关心(因为请求应该由其他工作实例提供服务)。

我说过我使用的是快速启动代码——这意味着在 IdentityServer 的启动中,有看起来像这样的代码......

    public void ConfigureServices(IServiceCollection services)  
{
services.AddMvc();

services.AddIdentityServer(options =>
{
options.Events.RaiseSuccessEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseErrorEvents = true;
})
.AddTemporarySigningCredential()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())

我假设我需要用证书替换 .AddTemporarySigningCredential() 逻辑,我的 Kubernetes 集群中运行的 IdentityServer 的所有实例都可以使用该证书。不知道 MVC 是如何工作的(MVC6 用于在 IdentityServer 服务中生成登录页面,这是我从示例代码中获得的 - 上面的链接) - 我想知道是否只是更改代码以使用在两者之间共享的正确证书所有服务都足以让原型(prototype) HA IdentityServer 集群正常工作吗?

通过工作,我的意思是我的期望是我可以在 Kubernetes 集群中运行 n 个 IdentityServer 实例,有一个 Kubernetes 服务作为我运行的许多 IdentityServer 的外观,并且能够使用多个 IdentityServer 实例可以共享数据,它们都为我的调用 Web 应用程序提供完全相同的权限,并且可以在一个或多个实例挂掉时处理彼此的请求。

如有任何帮助或见解,我们将不胜感激。

最佳答案

我想我已经解决了这个问题。为了解决我的问题,我做了两件事:

  1. 创建我自己的 X509 证书并在我的每个 IdentityServer 之间共享该证书。网上有很多关于如何创建有效证书的示例;我刚用过

    services.AddIdentityServer(...).AddSigningCredential(new X509Certificate2(bytes, "password")

    在我的创业类。

  2. 深入研究 MVC 框架代码,发现我需要实现 Key storage provider为了在提供登录页面的 Identity Server 的 MVC 部分的不同实例之间共享状态。

原来有一个Redis backed KSP available from NuGet ,这意味着我只需要在我的 Kube 集群中启动一个私有(private)的 redis 实例(在我的集群之外无法访问)来共享解密 secret 。

/* Note: Use an IP, or resolve from DNS prior to adding redis based key store as direct DNS resolution doesn't work for this inside a K8s cluster, though it works quite happily in a Windows environment. */  
var redis = ConnectionMultiplexer.Connect("1.2.3.4:6379");
services.AddDataProtection()
.PersistKeysToRedis(redis, "DataProtection-Keys");

我现在可以将我的身份服务扩展到 3 个实例,并让 Kube 服务充当所有可用实例的外观。我可以将日志视为身份服务之间 Kubernetes 循环请求,并且我的身份验证正如我预期的那样发生。

感谢那些在发表这篇文章之前对问题发表评论的人。

关于c# - 扩展 IdentityServer4 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45233415/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com