All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.lettuce.authx.TokenBasedRedisCredentialsProvider Maven / Gradle / Ivy

Go to download

Advanced and thread-safe Java Redis client for synchronous, asynchronous, and reactive usage. Supports Cluster, Sentinel, Pipelining, Auto-Reconnect, Codecs and much more.

The newest version!
/*
 * Copyright 2024, Redis Ltd. and Contributors
 * All rights reserved.
 *
 * Licensed under the MIT License.
 */
package io.lettuce.authx;

import io.lettuce.core.RedisCredentials;
import io.lettuce.core.RedisCredentialsProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.publisher.Sinks;
import redis.clients.authentication.core.Token;
import redis.clients.authentication.core.TokenAuthConfig;
import redis.clients.authentication.core.TokenListener;
import redis.clients.authentication.core.TokenManager;

/**
 * A {@link RedisCredentialsProvider} implementation that supports token-based authentication for Redis.
 * 

* This provider uses a {@link TokenManager} to manage and renew tokens, ensuring that the Redis client can authenticate with * Redis using a dynamically updated token. This is particularly useful in scenarios where Redis access is controlled via * token-based authentication, such as when Redis is integrated with an identity provider like EntraID. *

*

* The provider supports streaming of credentials and automatically emits new credentials whenever a token is renewed. It must * be used with {@link io.lettuce.core.ClientOptions.ReauthenticateBehavior#ON_NEW_CREDENTIALS} to automatically re-authenticate * connections whenever new tokens are emitted by the provider. *

*

* The lifecycle of this provider is externally managed. It should be closed when there are no longer any connections using it, * to stop the token management process and release resources. *

* * @since 6.6 */ public class TokenBasedRedisCredentialsProvider implements RedisCredentialsProvider, AutoCloseable { private static final Logger log = LoggerFactory.getLogger(TokenBasedRedisCredentialsProvider.class); private final TokenManager tokenManager; private final Sinks.Many credentialsSink = Sinks.many().replay().latest(); private TokenBasedRedisCredentialsProvider(TokenManager tokenManager) { this.tokenManager = tokenManager; } private void init() { TokenListener listener = new TokenListener() { @Override public void onTokenRenewed(Token token) { String username = token.getUser(); char[] pass = token.getValue().toCharArray(); RedisCredentials credentials = RedisCredentials.just(username, pass); credentialsSink.tryEmitNext(credentials); } @Override public void onError(Exception exception) { log.error("Token renew failed!", exception); } }; try { tokenManager.start(listener, false); } catch (Exception e) { credentialsSink.tryEmitError(e); tokenManager.stop(); throw new RuntimeException("Failed to start TokenManager", e); } } /** * Resolve the latest available credentials as a Mono. *

* This method returns a Mono that emits the most recent set of Redis credentials. The Mono will complete once the * credentials are emitted. If no credentials are available at the time of subscription, the Mono will wait until * credentials are available. * * @return a Mono that emits the latest Redis credentials */ @Override public Mono resolveCredentials() { return credentialsSink.asFlux().next(); } /** * Expose the Flux for all credential updates. *

* This method returns a Flux that emits all updates to the Redis credentials. Subscribers will receive the latest * credentials whenever they are updated. The Flux will continue to emit updates until the provider is shut down. * * @return a Flux that emits all updates to the Redis credentials */ @Override public Flux credentials() { return credentialsSink.asFlux().onBackpressureLatest(); // Provide a continuous stream of credentials } @Override public boolean supportsStreaming() { return true; } /** * Stop the credentials provider and clean up resources. *

* This method stops the TokenManager and completes the credentials sink, ensuring that all resources are properly released. * It should be called when the credentials provider is no longer needed. */ @Override public void close() { credentialsSink.tryEmitComplete(); tokenManager.stop(); } public static TokenBasedRedisCredentialsProvider create(TokenAuthConfig tokenAuthConfig) { return create(new TokenManager(tokenAuthConfig.getIdentityProviderConfig().getProvider(), tokenAuthConfig.getTokenManagerConfig())); } public static TokenBasedRedisCredentialsProvider create(TokenManager tokenManager) { TokenBasedRedisCredentialsProvider credentialManager = new TokenBasedRedisCredentialsProvider(tokenManager); credentialManager.init(); return credentialManager; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy