首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >扩展IdentityServer4服务

扩展IdentityServer4服务
EN

Stack Overflow用户
提问于 2017-07-21 08:59:26
回答 2查看 6K关注 0票数 20

我跟踪了IdentityServer4快速启动,并能够使用隐式授予的本地托管IdentityServer实例验证我的javascript网页(几乎与快速启动中提供的页面相同)。同样,我的IdentityServer与上面提到的快速启动中提供的几乎完全相同--它只是有一些定制的用户详细信息。

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

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

System.InvalidOperationException:防伪令牌无法解密。--> System.Security.Cryptography.CryptographicException:键环中没有找到密钥{19742e88-9dc6-44a0-9e89-e7b09db83329}。. trace =‘trace 1’>( Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData,UnprotectStatus& status& status)在Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(Byte[] protectedData,布尔ignoreRevocationErrors,布尔& requiresMigration,布尔&wasRevoked(在Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData)在Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken) -内部异常堆栈跟踪的结束-.还有更多.

所以-我明白我会收到这个错误,因为我的期望是同一个IdentityServer应该服务于它所显示的页面请求(否则防伪令牌会如何工作,对吧?),但是我想了解的是我如何在一个复制的环境中实现这个功能。

我不想在不同的IP/端口上托管多个身份服务器;我试图构建一个HA配置,如果其中一个IdentityServer死了,调用端点的任何东西都不会在意(因为请求应该由其他工作实例提供服务)。

我说过我使用的是快速启动代码--这意味着在启动IdentityServer时,有如下代码.

代码语言:javascript
运行
复制
    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应用程序提供完全相同的权限,并且可以在一个或多个实例死亡的情况下处理彼此的请求。

任何帮助或洞察力都将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-24 08:43:14

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

  1. 创建我自己的X509证书,并在我的每个IdentityServer之间共享这个证书。 services.AddIdentityServer(...).AddSigningCredential(new X509Certificate2(字节,“密码”) 在我的创业课上。
  2. 深入研究MVC框架代码,得出我需要实现一个密钥存储提供者,以便在身份服务器的MVC部分的不同实例之间共享状态,该部分为登录页面提供服务。

结果是有一个可从NuGet获得Redis支持的KSP,这意味着我只需要在Kube集群中拆分一个私有redis实例(在集群之外是不可访问的)来共享解密秘密。

代码语言:javascript
运行
复制
/* 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循环罗宾在身份服务之间的请求来查看日志,我的身份验证就像我所期望的一样。

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

票数 16
EN

Stack Overflow用户

发布于 2020-07-17 06:56:28

对于使用Kubernetes的用户,可以使用文件系统密钥存储提供程序

代码语言:javascript
运行
复制
public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo(@"/app/key-storage"));
}

其中,目录‘/app/key-存储’映射到nfs支持的持久卷。

代码语言:javascript
运行
复制
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-key-storage
spec:
  selector:
    matchLabels:
      type: nfs-pv
  storageClassName: manual
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Mi
代码语言:javascript
运行
复制
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv
  labels:
    type: nfs-pv
spec:
  storageClassName: manual
  capacity:
    storage: 10Mi
  accessModes:
    - ReadWriteMany
  nfs:
    server: <server>
    path: /<path>
  persistentVolumeReclaimPolicy: Delete

在国内流离失所者的部署中

代码语言:javascript
运行
复制
template:
  spec:
    containers:
      - name: <name>
        volumeMounts:
          - name: key-storage
            mountPath: /app/key-storage
            readOnly: false
    volumes:
      - name: key-storage
        persistentVolumeClaim:
        claimName: pvc-key-storage

你需要签名证书。这可以作为一个秘密添加,然后IDP部署可以使用另一个卷来挂载这个秘密(未显示)。

代码语言:javascript
运行
复制
apiVersion: v1
kind: Secret
metadata:
  name: cert-secret
  labels:
    app: <app-label>
type: Opaque
data:
  signingcert.pfx: <base64 cert value>
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45233415

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档