提问者:小点点

如何将JedisConnectionFactory配置为使用SSL,以免出现错误:“JedisDataException: ERR未加密连接被禁止”?


我有一个带有RLEC(RedisLabs Enterprise Cluster)用户界面的Redis数据库,该用户界面是为SSL连接设置的。

我有一个java应用程序,它能够使用Jedis连接到redis数据库。

这工作原理:

Jedis jedis = new Jedis(redisInfo.getHost(), redisInfo.getPort(), useSsl);

// make the connection
jedis.connect();

// authorize with our password
jedis.auth(redisInfo.getPassword());

环境变量:

"-Djavax.net.ssl.keyStoreType=PKCS12 -Djavax.net.ssl.keyStorePassword=iloveredis -Djavax.net.ssl.keyStore=$PWD/META-INF/clientKeyStore.p12 -Djavax.net.ssl.trustStoreType=JKS -Djavax.net.ssl.trustStorePassword=iloveredis -Djavax.net.ssl.trustStore=$PWD/META-INF/clientTrustStore.jks"

我还有一个Spring Boot应用程序,我正在尝试使用JedisConnectionFactory连接到Redis db,但我无法。(使用同一个应用程序,我可以连接到未启用SSL的Redis db)。

在my pom.xml中:

          <dependency>
              <groupId>org.springframework.data</groupId>
              <artifactId>spring-data-redis</artifactId>
              <version>2.1.4.RELEASE</version>
          </dependency>

          <dependency>
                 <groupId>redis.clients</groupId>
                 <artifactId>jedis</artifactId>
                 <version>2.9.0</version>
          </dependency>

在我的redis配置文件中:

@Configuration
@EnableRedisRepositories
public class RedisConfig {

@Bean
JedisConnectionFactory jedisConnectionFactory() {
   RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration();
   redisConfig.setHostName(redisInfo.getHost());
   redisConfig.setPort(redisInfo.getPort());
   redisConfig.setPassword(RedisPassword.of(redisInfo.getPassword()));
   boolean useSsl = env.getProperty("spring.redis.ssl", Boolean.class);
   JedisClientConfiguration jedisConfig;
   if (useSsl) {
          jedisConfig = JedisClientConfiguration
                                                                              .builder()
                                                                              .useSsl()
                                                                              .build(); 
   } else {
          jedisConfig = JedisClientConfiguration
                              .builder()
                              .build();                  
   }
    JedisConnectionFactory jcf = new JedisConnectionFactory(redisConfig, jedisConfig); 

    return jcf;
}



@Bean
public RedisTemplate<?, ?> redisTemplateJedis() {
   final RedisTemplate<byte[], byte[]> template = new RedisTemplate<>();
   template.setConnectionFactory(jedisConnectionFactory());
    template.setValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
    return template;
}

这是我遇到的错误:

org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisDataException: ERR unencrypted connection is prohibited

另一点是,出于测试目的,服务器和应用程序都使用自签名证书(可用于Jedis)。

我不知道如何配置JedisConfigurationFactory以避免出现此错误。


共1个答案

匿名用户

已编辑。

总结一下,我可以使用Jedis库启用SSL连接到Redis,但不能使用Spring库JedisConnectionFactory。

我在Pivotal Cloud Foundry(PCF)中尝试了这一点。

我写信给spring data redis的作者Mark Paluch,他建议我关闭自动重新配置以使其在PCF中工作。

我找到了关于关闭自动重新配置的页面:

https://docs.cloudfoundry.org/buildpacks/java/configuring-service-connections/spring-service-bindings.html#manual

Cloud Foundry将自动为您创建RedisConnectionFactory bean,因此我的JedisConnectionFactory没有被使用。

我不得不关闭自动重新配置。或者打开手动配置。

然后,我的JedisConnectionFactory bean(启用了SSL)开始实例化(以及云服务连接器的RedisConnectionFactory bean)。

我必须将我的JedisConnectionFactory bean设置为Primary,因为现在有两个连接工厂bean。

我也收到了一些关于意外终止流的异常。

我必须在JedisClientConfiguration中打开usePooling。

这是我向jira发布的关于这个问题的帖子(现在转到github):

https://github.com/spring-projects/spring-data-redis/issues/1542