Skip to content

Commit

Permalink
Readme doc on how to connect to Azure Managed Redis with Entra ID aut…
Browse files Browse the repository at this point in the history
…hentication (#3166)

* Readme doc on how to connect to Azure Managed Redis (AMR) and Azure Cache for Redis (ACR) with Entra ID authentication

* Spellcheck words list updated

* Formating

* Update docs/user-guide/connecting-redis.md

Co-authored-by: Tihomir Krasimirov Mateev <tihomir.mateev@redis.com>

* Apply suggestions from code review

Co-authored-by: Tihomir Krasimirov Mateev <tihomir.mateev@redis.com>

* Add section for Streaming Credentials

* Add section for Streaming Credentials - fix spell check

* Apply suggestions from code review

Co-authored-by: Tihomir Krasimirov Mateev <tihomir.mateev@redis.com>

---------

Co-authored-by: Tihomir Krasimirov Mateev <tihomir.mateev@redis.com>
  • Loading branch information
ggivo and tishun authored Feb 16, 2025
1 parent fc7bffb commit 06496ed
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 1 deletion.
7 changes: 6 additions & 1 deletion .github/wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -272,4 +272,9 @@ bom
ubuntu
behaviour
databind
jackson
jackson
ACR
AMR
Entra
authx
entraid
158 changes: 158 additions & 0 deletions docs/user-guide/connecting-redis.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,3 +237,161 @@ RedisClient client = RedisClient.create(redisUri);
client.shutdown();
```

## Streaming Credentials Provider
[Lettuce 6.6.0](https://github.com/redis/lettuce/releases/tag/6.6.0.RELEASE) extends `RedisCredentialsProvider` to support streaming credentials.
It is useful when you need to refresh credentials periodically. Example use cases include: token expiration, rotating credentials, etc.
Connection configured with `RedisCredentialsProvider` supporting streaming will be re-authenticated automatically when new credentials are emitted and `ReauthenticateBehavior` is set to `ON_NEW_CREDENTIALS`.

### Step 1 - Create a Streaming Credentials Provider
A simple example of a streaming credentials provider that emits new credentials.
```java
public class MyStreamingRedisCredentialsProvider implements RedisCredentialsProvider {

private final Sinks.Many<RedisCredentials> credentialsSink = Sinks.many().replay().latest();

@Override
public boolean supportsStreaming() {
return true;
}

@Override
public Mono<RedisCredentials> resolveCredentials() {
return credentialsSink.asFlux().next();
}

@Override
// Provide a continuous stream of credentials
public Flux<RedisCredentials> credentials() {
return credentialsSink.asFlux().onBackpressureLatest();
}

public void close() {
credentialsSink.tryEmitComplete();
}
// Emit new credentials when needed
public void emitCredentials(String username, char[] password) {
credentialsSink.tryEmitNext(new StaticRedisCredentials(username, password));
}

}
```
### Step 2 - Create a RedisURI with streaming credentials provider

```java
// Create a streaming credentials provider
MyStreamingRedisCredentialsProvider streamingCredentialsProvider = new MyStreamingRedisCredentialsProvider();

// Emit initial credentials
streamingCredentialsProvider.emitCredentials("testuser", "testpass".toCharArray());

// Enable automatic re-authentication
ClientOptions clientOptions = ClientOptions.builder()
// enable automatic re-authentication
.reauthenticateBehavior(ClientOptions.ReauthenticateBehavior.ON_NEW_CREDENTIALS)
.build();

// Create a RedisURI with streaming credentials provider
RedisURI redisURI = RedisURI.builder().withHost(HOST).withPort(PORT)
.withAuthentication(streamingCredentialsProvider)
.build();

// RedisClient
RedisClient redisClient = RedisClient.create(redisURI);
rediscClient.connect().sync().ping();

// ...
// Emit new credentials when needed
streamingCredentialsProvider.emitCredentials("testuser", "password-rotated".toCharArray());

```

## Microsoft Entra ID Authentication

[Lettuce 6.6.0](https://github.com/redis/lettuce/releases/tag/6.6.0.RELEASE) introduces built-in support for authentication with [Azure Managed Redis](https://azure.microsoft.com/en-us/products/managed-redis) and Azure Cache for Redis using Microsoft Entra ID (formerly Azure Active Directory). It enables seamless integration with Azure's Redis services by fetching authentication tokens and managing the token renewal in the background.
Integration is built on top of [redis-authx](https://github.com/redis/jvm-redis-authx-entraid) library, and provides support for:

- System-assigned managed identity
- User-assigned managed identity
- Service principal

You can learn more about managed identities in the [Microsoft Entra ID documentation](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/overview).

### Basic Usage

#### Pre-requisites
* [register an application and create a service principal](https://learn.microsoft.com/en-us/entra/identity-platform/app-objects-and-service-principals?tabs=browser) in Azure.
* Create a Redis cache in Azure and grant your service principal access: [AMR](https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/managed-redis/managed-redis-entra-for-authentication) or [ACR](https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-azure-active-directory-for-authentication) documentation.

#### Step 1 - Add the dependencies
Lettuce requires [redis-authx-entraid](https://github.com/redis/jvm-redis-authx-entraid/) dependency to provide Microsoft Entra ID authentication support. Make sure to include that dependency on your classpath.

If using Maven, add the following dependency to your `pom.xml`:

``` xml
<dependency>
<groupId>redis.clients.authentication</groupId>
<artifactId>redis-authx-entraid</artifactId>
<version>0.1.1-beta1</version>
</dependency>
```


### Step 2 - Create Entra ID enabled credentials provider
The lifecycle of the credentials provider is not managed by the Lettuce client. You can create it once and reuse it across multiple clients\connections. When no longer needed, you should close the provider to release resources `TokenBasedRedisCredentialsProvider#close`.

#### Create Microsoft Entra ID enabled credentials provider
```java
// Entra ID enabled credentials provider for Service Principle Identity with Client Secret
TokenBasedRedisCredentialsProvider credentialsSP;
try ( EntraIDTokenAuthConfigBuilder builder = EntraIDTokenAuthConfigBuilder.builder()) {
builder.clientId(CLIENT_ID)
.secret(CLIENT_SECRET)
.authority(AUTHORITY) // "https://login.microsoftonline.com/{YOUR_TENANT_ID}";
.scopes(SCOPES); // "https://redis.azure.com/.default";
credentialsSP = TokenBasedRedisCredentialsProvider.create(builder.build());
}
```

You can test the credentials provider by obtaining a token.

```java
// Test Entra ID credentials provider can resolve credentials
credentialsSP.resolveCredentials()
.doOnNext(c-> System.out.println(c.getUsername()))
.block();
```

### Step 3 - Enable automatic re-authentication
Microsoft Entra ID tokens have a limited lifetime. Lettuce provides a mechanism to automatically re-authenticate when new credentials are emitted by a `RedisCredentialsProvider`.
```java
// Enable automatic re-authentication
ClientOptions clientOptions = ClientOptions.builder()
.reauthenticateBehavior(ClientOptions.ReauthenticateBehavior.ON_NEW_CREDENTIALS)
.build();
```

### Step 4 - Connect with Entra ID enabled credentials provider

```java
// Use Entra ID credentials provider
RedisURI redisURI = RedisURI.builder()
.withHost(HOST)
.withPort(PORT)
.withAuthentication(credentialsSP).build();

// RedisClient
RedisClient redisClient = RedisClient.create(redisURI1);
redisClient.setOptions(clientOptions);

try {
redisClient.setOptions(clientOptions);
// Connect with Entra ID credentials provider
try (StatefulRedisConnection<String, String> user1 = redisClient.connect(StringCodec.UTF8)) {
System.out.println("Connected to redis as :" + user1.sync().aclWhoami());
System.out.println("Db size :" + user1.sync().dbsize());
}
} finally {
redisClient.shutdown(); // Shutdown Redis client and close connections
credentialsSP.close(); // Shutdown Entra ID Credentials provider
}
```

0 comments on commit 06496ed

Please sign in to comment.