Identityserver4 关联失败,远程登录。AspNet核心身份服务器

Identityserver4 关联失败,远程登录。AspNet核心身份服务器,identityserver4,openid-connect,protection,Identityserver4,Openid Connect,Protection,当我接收到相关失败错误时,试图对这个过程的工作原理有一些基本的了解。让我首先描述一下我遇到的问题 QAT工作不正常,配置如下: 我在QAT的负载平衡器后面运行了一台Identity Server。 发送到负载平衡器的所有请求都是https。 转发到每个应用服务器(本例中为两个独立的服务器)的流量是http。 Netscaler正在向标头添加所有必要的X转发项 我还有另一个应用程序,它也位于QAT负载平衡器的后面。 netscaler将把流量转发给两个独立的服务器来承载此应用程序。 此应用程序配置

当我接收到相关失败错误时,试图对这个过程的工作原理有一些基本的了解。让我首先描述一下我遇到的问题

QAT工作不正常,配置如下:

我在QAT的负载平衡器后面运行了一台Identity Server。
发送到负载平衡器的所有请求都是https。 转发到每个应用服务器(本例中为两个独立的服务器)的流量是http。 Netscaler正在向标头添加所有必要的X转发项

我还有另一个应用程序,它也位于QAT负载平衡器的后面。 netscaler将把流量转发给两个独立的服务器来承载此应用程序。 此应用程序配置为使用netscaler的X转发信息。 它设计用于使用上述身份服务器进行身份验证

我的问题是,当我部署到QAT时,第二个应用程序和Identity Server之间会出现一个永无止境的循环。这对我来说很奇怪,因为我的SYS环境工作得很好。My sys环境有一个单独的Identity Server实例和提到的第二个应用程序(除了每个应用程序只有一个实例被转发到)。这也通过netscaler完成了前面提到的所有X-Forwarded魔法

在这两种情况下,设置是相同的。唯一的区别是QAT有多台服务器托管每个应用程序,而SYS只有一台服务器托管每个应用程序

我的问题是,为什么会有不同的表现? 为什么这在sys中有效,而在qa中无效

我认为在这一点上,我们可以排除回调路径、cookie设置等。。。b/c它在系统中工作。 我是否需要在identity server和其他应用程序中实现一些数据保护密钥中间件?在这方面,我真的不理解数据保护密钥。identity server和单独的应用程序是否都需要将它们的密钥存储在相同的位置(无论是在数据库还是文件系统中),以便能够解密存储在cookie中的信息


非常感谢您的帮助。

数据保护密钥肯定是问题所在。我的解决办法很简单。将加密密钥保存为部署过程的一部分,创建一个IXmlRepository,然后将其添加到启动中。简单的豌豆

    using Microsoft.AspNetCore.DataProtection.Repositories;
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Linq;

namespace Myapp.Encryption.Repositories
{
    public class EncryptionRepository : IXmlRepository
    {
        private String Key { get; set; }
    public EncryptionRepository()
    {
        var year = Convert.ToString(DateTime.Now.Year + 2);
        var key = "<key id=\"983440f7-626b-46e4-8bfa-7c3d6d9d4619\" version=\"1\">" + 
                  "    <creationDate>2019-11-13T17:42:58.889085Z</creationDate>" + 
                  "    <activationDate>2019-11-13T17:42:58.3843715Z</activationDate>" + 
                  "    <expirationDate>" + year + "-02-11T17:42:58.3843715Z</expirationDate>" + 
                  "    <descriptor deserializerType=\"Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60\">" + 
                  "        <descriptor>" + 
                  "            <encryption algorithm=\"AES_256_CBC\" />" + 
                  "            <validation algorithm=\"HMACSHA256\" />" + 
                  "            <masterKey p4:requiresEncryption=\"true\" xmlns:p4=\"http://schemas.asp.net/2015/03/dataProtection\">" + 
                  "                <value>{{Your Encryption Key }}</value>" + 
                  "            </masterKey>" + 
                  "        </descriptor>" + 
                  "    </descriptor>" + 
                  "</key>";
        Key = key;
    }

    public IReadOnlyCollection<XElement> GetAllElements()
    {
        var collection = new List<XElement>();
        collection.Add(XElement.Parse(Key));
        return collection;
    }

    public void StoreElement(XElement element, String friendlyName)
    {
        // Not required as key is hard coded
    }
}
使用Microsoft.AspNetCore.DataProtection.Repositories;
使用制度;
使用System.Collections.Generic;
使用系统文本;
使用System.Xml.Linq;
命名空间Myapp.Encryption.Repositories
{
公共类EncryptionRepository:IXmlRepository
{
私有字符串密钥{get;set;}
公共加密存储库()
{
var year=Convert.ToString(DateTime.Now.year+2);
var key=”“+
“2019-11-13T17:42:58.889085Z”+
“2019-11-13T17:42:58.3843715Z”+
“+年份+”-02-11T17:42:58.3843715Z”+
"    " + 
"        " + 
"            " + 
"            " + 
"            " + 
“{{您的加密密钥}}”+
"            " + 
"        " + 
"    " + 
"";
钥匙=钥匙;
}
公共IReadOnlyCollection GetAllegements()
{
var collection=新列表();
collection.Add(XElement.Parse(Key));
回收;
}
公共void存储元素(XElement元素,字符串friendlyName)
{
//不需要,因为钥匙是硬编码的
}
}
}

services.AddSingleton();
services.AddDataProtection().AddKeyManagementOptions(a=>a.XmlRepository=(services.BuildServiceProvider()).GetService());

问题肯定出在数据保护密钥上。我的解决办法很简单。将加密密钥保存为部署过程的一部分,创建一个IXmlRepository,然后将其添加到启动中。简单的豌豆

    using Microsoft.AspNetCore.DataProtection.Repositories;
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Linq;

namespace Myapp.Encryption.Repositories
{
    public class EncryptionRepository : IXmlRepository
    {
        private String Key { get; set; }
    public EncryptionRepository()
    {
        var year = Convert.ToString(DateTime.Now.Year + 2);
        var key = "<key id=\"983440f7-626b-46e4-8bfa-7c3d6d9d4619\" version=\"1\">" + 
                  "    <creationDate>2019-11-13T17:42:58.889085Z</creationDate>" + 
                  "    <activationDate>2019-11-13T17:42:58.3843715Z</activationDate>" + 
                  "    <expirationDate>" + year + "-02-11T17:42:58.3843715Z</expirationDate>" + 
                  "    <descriptor deserializerType=\"Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60\">" + 
                  "        <descriptor>" + 
                  "            <encryption algorithm=\"AES_256_CBC\" />" + 
                  "            <validation algorithm=\"HMACSHA256\" />" + 
                  "            <masterKey p4:requiresEncryption=\"true\" xmlns:p4=\"http://schemas.asp.net/2015/03/dataProtection\">" + 
                  "                <value>{{Your Encryption Key }}</value>" + 
                  "            </masterKey>" + 
                  "        </descriptor>" + 
                  "    </descriptor>" + 
                  "</key>";
        Key = key;
    }

    public IReadOnlyCollection<XElement> GetAllElements()
    {
        var collection = new List<XElement>();
        collection.Add(XElement.Parse(Key));
        return collection;
    }

    public void StoreElement(XElement element, String friendlyName)
    {
        // Not required as key is hard coded
    }
}
使用Microsoft.AspNetCore.DataProtection.Repositories;
使用制度;
使用System.Collections.Generic;
使用系统文本;
使用System.Xml.Linq;
命名空间Myapp.Encryption.Repositories
{
公共类EncryptionRepository:IXmlRepository
{
私有字符串密钥{get;set;}
公共加密存储库()
{
var year=Convert.ToString(DateTime.Now.year+2);
var key=”“+
“2019-11-13T17:42:58.889085Z”+
“2019-11-13T17:42:58.3843715Z”+
“+年份+”-02-11T17:42:58.3843715Z”+
"    " + 
"        " + 
"            " + 
"            " + 
"            " + 
“{{您的加密密钥}}”+
"            " + 
"        " + 
"    " + 
"";
钥匙=钥匙;
}
公共IReadOnlyCollection GetAllegements()
{
var collection=新列表();
collection.Add(XElement.Parse(Key));
回收;
}
公共void存储元素(XElement元素,字符串friendlyName)
{
//不需要,因为钥匙是硬编码的
}
}
}

services.AddSingleton();
services.AddDataProtection().AddKeyManagementOptions(a=>a.XmlRepository=(services.BuildServiceProvider()).GetService());

注意-这不是我的最终解决方案,我不打算长期使用这种方法。我打算创建一个服务来存储和检索密钥。此时,我将修改Store元素代码,以便在密钥过期时实际生成密钥。。。我提供这只是一个解释…也值得注意。Netscaler上的粘性会话修复了该问题