简体   繁体   English

SSL 连接到 Redis 与 StackExchange.Redis

[英]SSL connectivity to Redis with StackExchange.Redis

I am having a very weird issue with StackExchange.Redis to connect with Redis. StackExchange.Redis 与 Redis 连接时,我遇到了一个非常奇怪的问题。

I have enabled SSL on Redis database and I am not able to connect from client to Redis server with SSL certificate with below code. I have enabled SSL on Redis database and I am not able to connect from client to Redis server with SSL certificate with below code.

  static RedisConnectionFactory()
        {
            try
            {
                string connectionString = "rediscluster:13184";
                var options = ConfigurationOptions.Parse(connectionString);
                options.Password = "PASSWORD";
                options.AllowAdmin = true;
                options.AbortOnConnectFail = false;
                options.Ssl = true;
                options.SslHost = "HOSTNAME";
                var certificate = GetCertificateFromThubprint();
                options.CertificateSelection += delegate
                {
                    return certificate;
                };

                Connection = new Lazy<ConnectionMultiplexer>(
               () => ConnectionMultiplexer.Connect(options)
                );
            }
            catch (Exception ex)
            {
                throw new Exception("Unable to connect to Cache Server " + ex);
            }

        }

        public static ConnectionMultiplexer GetConnection() => Connection.Value;

        public static IEnumerable<RedisKey> GetCacheKeys()
        {

            return GetConnection().GetServer("rediscluster", 13184).Keys();
        }

        // Find certificate based on Thumbprint
        private static X509Certificate2 GetCertificateFromThubprint()
        {
  // Find certificate from "certificate store" based on thumbprint and return
StoreName CertStoreName = StoreName.Root;
            string PFXThumbPrint = "NUMBER";
            X509Store certLocalMachineStore = new X509Store(CertStoreName, StoreLocation.LocalMachine);
            certLocalMachineStore.Open(OpenFlags.ReadOnly);
            X509Certificate2Collection certLocalMachineCollection = certLocalMachineStore.Certificates.Find(
                                       X509FindType.FindByThumbprint, PFXThumbPrint, true);
            certLocalMachineStore.Close();
 return certLocalMachineCollection[0];
       }

However, If I create a console application and connect to Redis with above code then I am able to connect, but If I used same code from my web application to connect to redis then I am not able to connect.但是,如果我创建一个控制台应用程序并使用上述代码连接到 Redis,那么我可以连接,但如果我使用 web 应用程序中的相同代码连接到 Z86A1B907D54BF7010394BF316E183E7,则无法连接。

Not sure if I am missing something.不确定我是否遗漏了什么。

Also, I went through "mgravell" post另外,我浏览了“mgravell” 帖子

In that post he has configured " CertificateValidation " method, In my scenario I want Redis to validate SSL certificate.在那篇文章中,他配置了“ CertificateValidation ”方法,在我的场景中,我希望 Redis 验证 SSL 证书。 so I have not implementation validation.所以我没有实现验证。 And implemented "CertificateSelection" method to provide client certificate.并实现了“CertificateSelection”方法来提供客户端证书。

You can try to validate the cert using CertificateValidation.您可以尝试使用 CertificateValidation 验证证书。 I tried the following code and it worked for me:我尝试了以下代码,它对我有用:

options.CertificateValidation += ValidateServerCertificate;

... ...

public static bool ValidateServerCertificate(
        object sender,
        X509Certificate certificate,
        X509Chain chain,
        SslPolicyErrors sslPolicyErrors)
    {
        if (sslPolicyErrors == SslPolicyErrors.None)
            return true;

        Console.WriteLine("Certificate error: {0}", sslPolicyErrors);

        return false;
    }

In cases like this where you are using a client certificate and it works in a console app but does not work for some other application (you don't say but I guess from an IIS hosted web app), it almost always has to do with whether the account has permission to access the private key.在这种情况下,您使用客户端证书并且它适用于控制台应用程序但不适用于其他应用程序(您没有说,但我猜来自 IIS 托管的 web 应用程序),它几乎总是与账户是否有访问私钥的权限。

The console app runs with your account which probably has access to the private key.控制台应用程序使用您可能有权访问私钥的帐户运行。

To give an account access授予帐户访问权限

  1. open the Local Computer certificate store打开本地计算机证书存储
  2. find your client certificate找到您的客户证书
  3. right click and choose "All tasks -> Manage Provate Keys..."右键单击并选择“所有任务 -> 管理 Provate Keys...”
  4. click "Add..." and add the account.单击“添加...”并添加帐户。

Note: if your adding an IIS App Pool account the format is: IIS APPPOOL<my app pool name>注意:如果您添加 IIS 应用程序池帐户,格式为:IIS APPPOOL<my app pool name>

Location should be the local machine and not a domain.位置应该是本地机器而不是域。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM