Skip to content

Redis ACL Auth NOPERM Issue #1379

@etherrien

Description

@etherrien

Bug Report

When trying to use Redis 6 ACL Auth with username and password there is a NOPERM error.

Current Behavior

Stack trace
URI: redis://admin:admin@localhost
Exception in thread "main" io.lettuce.core.RedisConnectionException: Unable to connect to localhost:6379
	at [email protected]/io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:78)
	at [email protected]/io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:56)
	at [email protected]/io.lettuce.core.AbstractRedisClient.getConnection(AbstractRedisClient.java:295)
	at [email protected]/io.lettuce.core.RedisClient.connect(RedisClient.java:214)
	at [email protected]/io.lettuce.core.RedisClient.connect(RedisClient.java:199)
	at lettuceTest/lettuceTest.RedisCacheWriter.completeConstructor(RedisCacheWriter.java:71)
	at lettuceTest/lettuceTest.RedisCacheWriter.<init>(RedisCacheWriter.java:49)
	at lettuceTest/lettuceTest.RedisCacheWriter.main(RedisCacheWriter.java:41)
Caused by: io.lettuce.core.RedisCommandExecutionException: NOPERM this user has no permissions to run the 'hello' command or its subcommand
	at [email protected]/io.lettuce.core.internal.ExceptionFactory.createExecutionException(ExceptionFactory.java:137)
	at [email protected]/io.lettuce.core.internal.ExceptionFactory.createExecutionException(ExceptionFactory.java:110)
	at [email protected]/io.lettuce.core.protocol.AsyncCommand.completeResult(AsyncCommand.java:120)
	at [email protected]/io.lettuce.core.protocol.AsyncCommand.complete(AsyncCommand.java:111)
	at [email protected]/io.lettuce.core.protocol.CommandHandler.complete(CommandHandler.java:645)
	at [email protected]/io.lettuce.core.protocol.CommandHandler.decode(CommandHandler.java:605)
	at [email protected]/io.lettuce.core.protocol.CommandHandler.channelRead(CommandHandler.java:556)
	at [email protected]/io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at [email protected]/io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at [email protected]/io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at [email protected]/io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
	at [email protected]/io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at [email protected]/io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at [email protected]/io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
	at [email protected]/io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
	at [email protected]/io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
	at [email protected]/io.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:615)
	at [email protected]/io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:578)
	at [email protected]/io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
	at [email protected]/io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
	at [email protected]/io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at [email protected]/io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:834)

Input Code

Input Code
    public static void main(String args[]) {
        RedisCacheWriter redis = new RedisCacheWriter();
    }
    
    public RedisCacheWriter() {
        RedisURI uri = getURI();
        client = RedisClient.create(uri);
        System.out.println("URI: " + uri);

        completeConstructor();
    }
    
    private void completeConstructor() {
        if (encryptionEnabled && redisTruststorePath != null && !redisTruststorePath.isEmpty()) {
            SslOptions sslOptions;
            if (redisKeystorePath != null && !redisKeystorePath.isEmpty()) {
                sslOptions = SslOptions.builder()
                        .jdkSslProvider()
                        .keystore(new File(redisKeystorePath), redisKeystorePass)
                        .truststore(new File(redisTruststorePath), redisTruststorePass)
                        .build();
            }
            else {
                sslOptions = SslOptions.builder()
                        .jdkSslProvider()
                        .truststore(new File(redisTruststorePath), redisTruststorePass)
                        .build();
            }
            client.setOptions(ClientOptions.builder().sslOptions(sslOptions).build());
        }
        
        connection = client.connect();
        
        System.out.println("connected");

        connection.sync().set("abc", "value");
        
        preDestroy();
    }

    public void preDestroy() {
        connection.close();
        client.shutdown();
    }
    
    public RedisURI getURI() {
        if (redisPass == null || redisPass.toString().isEmpty()) {
            // Don't use password or username
            return RedisURI.Builder.redis(hostConfig, portConfig).withSsl(encryptionEnabled).withVerifyPeer(false).build();
        }
        else if (redisUser == null || redisUser.isEmpty()) {
          // Use password without ACL username
            return RedisURI.Builder.redis(hostConfig, portConfig).withSsl(encryptionEnabled).withVerifyPeer(false)
                    .withPassword(redisPass).build();
        }
        // Use ACL username and password
        return RedisURI.Builder.redis(hostConfig, portConfig).withSsl(encryptionEnabled).withVerifyPeer(false)
                .withAuthentication(redisUser, redisPass).build();
    }

Expected behavior/code

To connect to Redis with no issues.

Environment

  • Lettuce version(s): 6.0.0.M1
  • Redis version: redis:6.0-alpine (Currently 6.0.5)

Additional context

Code works fine with no Auth, but once Auth is on I get that error. Redis is being run from a docker container, and I know Redis has Auth enabled correctly due to having to log in on the CLI with admin:admin as well as my C# client connecting fine with Auth enabled or disabled.

Metadata

Metadata

Assignees

No one assigned

    Labels

    status: declinedA suggestion or change that we dont feel we should currently applystatus: waiting-for-feedbackWe need additional information before we can continue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions