我已经按照IdentityServer4快速入门并且可以使用隐式授权,通过一个本地实例的 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}。 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 --- ...更多错误信息...
所以我理解我得到这个错误是因为期望同一个 IdentityServer 应该服务于它显示的页面的请求(否则防伪标记如何工作,对吧?),但我试图理解的是如何在复制的环境中使其工作。
我不想在不同的 IP/端口上托管多个身份验证服务器。我试图构建一个高可用配置,如果一个 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应用程序提供完全相同的授权,并且可以在一个或多个实例出现故障时处理彼此的请求。
任何帮助或见解都将不胜感激。
.AddSigningCredential
。但我不确定这是否是唯一的问题,因为我计划做一些非常类似且相当有趣的事情。 - Boas Enkler