为什么我在使用Spring Boot时会收到“NOAUTH身份验证失败”的提示?

4
我有一个带密码的简单redis服务器正在运行,我想从我的Spring Boot应用程序与其通信。我查看这里并发现有一个spring.redis.password,因此我的应用程序-local.yml(使用-Dspring.profiles.active=local运行)看起来像...
spring:
  redis:
    password: ... 

但是当我运行时,会收到以下错误信息:

需要进行身份验证(NOAUTH Authentication required)

我漏掉了什么吗?我可以像这样通过node.js连接...

import redis from "redis";

const client = redis.createClient({
 password: "..."
});

额外的代码

@Bean
LettuceConnectionFactory redisConnectionFactory(){
    RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
    return new LettuceConnectionFactory(config);
}

@Bean
public RedisTemplate<String, Object> redisTemplate(){
    RedisTemplate<String, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(redisConnectionFactory());
    return template;
}

也尝试了...

@Bean
LettuceConnectionFactory redisConnectionFactory(){
    RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
    if (redisPassword != null){
        config.setPassword(redisPassword);
    }
    return new LettuceConnectionFactory(config);
}

虽然这样能够正常运行,但它似乎过于冗长,因为它只是一个标准属性。

3个回答

3

如果您需要更简洁的配置,可以从您的配置代码中删除RedisConnectionFactory bean,并只将RedisConnectionFactory bean注入到您的redisTemplate中。 redisConnectionFactory 将使用来自application.yml的属性进行填充:

@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
    RedisTemplate<String, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
}

在这种情况下,Spring 默认注入了 LettuceConnectionFactory
问题出在这里:new RedisStandaloneConfiguration()。如果你查看构造函数的代码,你会发现创建了一个空密码,除了调用setter方法之外没有其他设置方式。
旧答案:你需要通过 RedisProperties 类从 application.yml 中获取数据。尝试这样做:
@Bean
RedisConnectionFactory redisConnectionFactory(RedisProperties props) {
    RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();

    config.setPassword(props.getPassword());

    return new LettuceConnectionFactory(config);
}

@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
    RedisTemplate<String, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
}

这里的props包含来自spring.redis部分的属性。

这是正确的,但似乎有点啰嗦。如果它是默认属性,为什么不自动配置呢?例如,我不必将主机设置为127.0.0.1。 - JGleason
此答案总体来说过于冗长,请参考我的版本,它只需要设置密码即可。 - JGleason
主机和端口是自动配置的,我只是为了以防万一,将它们放在这里,以便您需要使用redis而不是localhost:6379启动服务。密码应该手动设置。 - nkrivenko
更新了我的答案,使用更简洁的配置。 - nkrivenko
现在更新后的答案不包括密码部分了,对吧?那个是原问题的解决方案。 - JGleason
它不包括密码部分。原问题的答案是删除RedisConnectionFactory bean,让Spring为您创建一个。创建的RedisConnectionFactory将使用来自application.yml的属性进行填充。 - nkrivenko

1
我的应用程序在使用Spring Boot v2.2.4.RELEASE时运行得很好。迁移到Spring v3.1.1后,出现了与作者提到的相同问题。
我尝试了几种方法,包括nkrivenko提出的答案,这个方法起作用了。然而,下面是我后来找到并最终接受为正确解决方案的方法:
在application.yaml(.property)文件中,我之前有以下内容:
spring:
  redis:
    client-name: JEDIS
    timeout: 3000
    port: ${REDIS_PORT:6379}
    host: ${REDIS_HOSTNAME:localhost}
    password: ${REDIS_PASSWORD:theRedisPasswordHere}

感谢IntelliJ IDEA建议在spring和redis之间使用数据包,因为这种结构已经被弃用。现在它看起来并且工作正常,无需进行任何代码更改。
spring:
  data:
    redis:
      client-name: JEDIS
      timeout: 3000
      port: ${REDIS_PORT:6379}
      host: ${REDIS_HOSTNAME:localhost}
      password: ${REDIS_PASSWORD:theRedisPasswordHere}

在yaml文件中在spring:和redis:之间添加data:解决了问题。 - undefined

0

对我来说,问题在于Spring和Redis的版本(2.1.4),升级到新版本后,它可以正常工作。请使用以下内容:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.9.RELEASE</version>
</parent>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>2.3.9.RELEASE</version>
</dependency>

我使用Redis Sentinel,我的属性如下:

spring.redis.database=0
spring.redis.sentinel.master=
spring.redis.sentinel.nodes=
spring.redis.sentinel.password=
spring.redis.password=
spring.redis.timeout=60000

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接