【发布时间】:2017-12-27 06:07:04
【问题描述】:
我已遵循IdentityServer4 quickstarts 并能够使用隐式授权使用本地化的 IdentityServer 实例验证我的 javascript 网页(与快速入门中提供的几乎相同)。同样,我的 IdentityServer 与上面提到的快速入门中提供的几乎完全相同 - 它只是有一些自定义用户详细信息。
然后,我将我的应用程序(C# .NET Core)移动到一个 docker 容器中,并在 Kubernetes 集群(单个实例)中托管了这个实例,并创建了一个 Kubernetes 服务(一个或多个“真实”服务的外观)让我可以从集群外部访问身份服务器。我可以修改我的 JavaScript 网页并将其指向我的 Kubernetes 服务,它仍然会非常高兴地显示登录页面,并且它似乎可以按预期工作。
当我将 IdentityServer 扩展到三个实例(均在单个 Kubernetes 服务之后提供)时,我开始遇到问题。 Kubernetes 服务轮询对每个身份服务器的请求,所以第一个会显示登录页面,但第二个会在我按下登录按钮后尝试处理身份验证。这会导致以下错误:
System.InvalidOperationException: 无法使用防伪令牌 解密。 ---> System.Security.Cryptography.CryptographicException: 密钥 {19742e88-9dc6-44a0-9e89-e7b09db83329} 钥匙圈。在 Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(字节[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& 状态)在 Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(字节[] protectedData,布尔型 ignoreRevocationErrors,布尔型& requiresMigration, Boolean& wasRevoked) 在 Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(字节[] 受保护数据)在 Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryTokenSerializer.Deserialize(字符串 serializedToken) --- 内部异常堆栈跟踪结束 --- ......还有更多......
所以 - 我知道我收到了这个错误,因为期望同一个 IdentityServer 应该为它显示的页面的请求提供服务(否则防伪令牌将如何工作,对吗?),但我我想了解的是如何在复制环境中进行这项工作。
我不想在不同的 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 服务中生成登录页面,我从上面的示例代码中获得 - 我想知道是否只是更改代码以使用在之间共享的正确证书所有服务都足以让原型 HA IdentityServer 集群正常工作吗?
通过工作,我的意思是我的期望是我可以在 Kubernetes 集群中运行 n 个 IdentityServer 实例,让 Kubernetes 服务充当我运行的许多 IdentityServer 的外观,并且能够使用多个 IdentityServer 实例可以共享数据,只要它们都为我的调用 Web 应用程序提供完全相同的权限,并且可以在一个或多个实例死亡的情况下处理彼此的请求。
任何帮助或见解将不胜感激。
【问题讨论】:
-
添加 TemporarySingingCrendentials 将罐。为每个 pod 生成不同的值。你肯定需要一个静态证书。见
.AddSigningCredential但我不确定这是否是唯一的问题。因为我打算做一些非常相似的事情,这很有趣 -
我们在负载平衡环境中使用 Identity Server 没有问题,但我们没有使用涉及由 IdSvr 生成的登录页面的流程。我们使用单个证书进行签名(不是临时证书),而且设置/测试很简单,因此您应该能够很快确定您的问题是临时证书还是其他问题。
-
@Mashton 很高兴知道;我之前遇到了一些其他问题,所以还没有机会尝试 Boas 建议的 .AddSigningCredential() 。当我更新证书时我会更新 - 可能在周末之后。
-
为什么这篇文章被否决了?如果这样做的人可以留下便条说明他们认为错误的地方,那就太好了。
标签: c# asp.net-mvc kubernetes scaling identityserver4