0

我在使用 StackExchange.Redis 连接 Redis 时遇到了一个非常奇怪的问题。

我在 Redis 数据库上启用了 SSL,但我无法使用 SSL 证书从客户端连接到 Redis 服务器,代码如下。

  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];
       }

但是,如果我创建一个控制台应用程序并使用上述代码连接到 Redis,那么我可以连接,但是如果我使用 Web 应用程序中的相同代码连接到 Redis,那么我将无法连接。

不确定我是否遗漏了什么。

另外,我浏览了“mgravell”帖子

在那篇文章中,他配置了“ CertificateValidation ”方法,在我的场景中,我希望 Redis 验证 SSL 证书。所以我没有实现验证。并实现了“CertificateSelection”方法来提供客户端证书。

4

2 回答 2

2

您可以尝试使用 CertificateValidation 验证证书。我尝试了以下代码,它对我有用:

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;
    }
于 2019-10-16T09:38:22.047 回答
0

在这种情况下,您使用客户端证书并且它适用于控制台应用程序但不适用于某些其他应用程序(您没有说,但我猜来自 IIS 托管的 Web 应用程序),它几乎总是与账户是否有访问私钥的权限。

控制台应用程序使用您可能有权访问私钥的帐户运行。

授予帐户访问权限

  1. 打开本地计算机证书存储
  2. 找到您的客户证书
  3. 右键单击并选择“所有任务 -> 管理 Provate Keys...”
  4. 单击“添加...”并添加帐户。

注意:如果您添加 IIS 应用程序池帐户,格式为:IIS APPPOOL<我的应用程序池名称>

位置应该是本地机器而不是域。

于 2020-10-02T13:51:34.050 回答