Skip to content

Commit 241fc32

Browse files
DOC-4819 implemented feedback
1 parent 5adcc32 commit 241fc32

File tree

1 file changed

+112
-64
lines changed
  • content/develop/clients/lettuce

1 file changed

+112
-64
lines changed

content/develop/clients/lettuce/amr.md

Lines changed: 112 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ You can authenticate using a system-assigned or user-assigned
2424
or a [service principal](https://learn.microsoft.com/en-us/entra/identity-platform/app-objects-and-service-principals),
2525
letting `redis-authx-entraid` fetch and renew the authentication tokens for you automatically.
2626

27+
See
28+
[Use Microsoft Entra for cache authentication](https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-azure-active-directory-for-authentication)
29+
in the Microsoft docs to learn how to configure Azure to use Entra ID authentication.
30+
2731
## Install
2832

2933
Install [`Lettuce`]({{< relref "/develop/clients/lettuce" >}}) first,
@@ -47,19 +51,24 @@ If you are using Gradle, add the following dependency to your
4751
implementation 'redis.clients.authentication:redis-authx-entraid:0.1.1-beta1'
4852
```
4953

50-
## Create a `TokenAuthConfig` instance
54+
## Create a `TokenBasedRedisCredentialsProvider` instance
5155

52-
The `TokenAuthConfig` class contains the authentication details that you
56+
The `TokenBasedRedisCredentialsProvider` class contains the authentication details that you
5357
must supply when you connect to Redis. Chain the methods of the
5458
`EntraIDTokenAuthConfigBuilder` class together (starting with the `builder()`
5559
method) to include the details you need, as shown in the following example:
5660

5761
```java
58-
TokenAuthConfig authConfig = EntraIDTokenAuthConfigBuilder.builder()
59-
.secret("<secret>")
60-
.authority("<authority>")
61-
// Other options...
62-
.build();
62+
TokenBasedRedisCredentialsProvider credentials;
63+
64+
try ( EntraIDTokenAuthConfigBuilder builder = EntraIDTokenAuthConfigBuilder.builder()) {
65+
builder.clientId(CLIENT_ID)
66+
.secret(CLIENT_SECRET)
67+
.authority(AUTHORITY) // "https://login.microsoftonline.com/{YOUR_TENANT_ID}";
68+
.scopes(SCOPES); // "https://redis.azure.com/.default";
69+
70+
credentials = TokenBasedRedisCredentialsProvider.create(builder.build());
71+
}
6372
```
6473

6574
Some of the details you can supply are common to different use cases:
@@ -68,11 +77,23 @@ Some of the details you can supply are common to different use cases:
6877
- `authority()`: A string containing the [authority](https://learn.microsoft.com/en-us/entra/identity-platform/msal-client-application-configuration#authority)
6978
URL.
7079
- `scopes()`: A set of strings defining the [scopes](https://learn.microsoft.com/en-us/entra/identity-platform/scopes-oidc)
71-
you want to apply.
80+
you want to apply. Configure your client application to acquire a Microsoft Entra token for scope, `https://redis.azure.com/.default` or `acca5fbb-b7e4-4009-81f1-37e38fd66d78/.default`
81+
with the
82+
[Microsoft Authentication Library (MSAL)](https://learn.microsoft.com/en-us/entra/identity-platform/msal-overview)
7283

7384
You can also add configuration to authenticate with a [service principal](#serv-principal)
7485
or a [managed identity](#mgd-identity) as described in the sections below.
7586

87+
When you have created your `TokenBasedRedisCredentialsProvider` instance, you may want to
88+
test it by obtaining a token, as shown in the folowing example:
89+
90+
```java
91+
// Test that the Entra ID credentials provider can resolve credentials.
92+
credentials.resolveCredentials()
93+
.doOnNext(c-> System.out.println(c.getUsername()))
94+
.block();
95+
```
96+
7697
### Configuration for a service principal {#serv-principal}
7798

7899
Add `clientId()` to the `EntraIDTokenAuthConfigBuilder` chain to specify
@@ -82,10 +103,16 @@ a parameter. (See the
82103
for more information about service principals.)
83104

84105
```java
85-
TokenAuthConfig authConfig = EntraIDTokenAuthConfigBuilder.builder()
86-
.clientId("<CLIENT-ID>")
87-
// ...
88-
.build();
106+
TokenBasedRedisCredentialsProvider credentials;
107+
108+
try ( EntraIDTokenAuthConfigBuilder builder = EntraIDTokenAuthConfigBuilder.builder()) {
109+
builder.clientId(CLIENT_ID)
110+
.secret(CLIENT_SECRET)
111+
.authority(AUTHORITY) // "https://login.microsoftonline.com/{YOUR_TENANT_ID}";
112+
.scopes(SCOPES); // "https://redis.azure.com/.default";
113+
114+
credentials = TokenBasedRedisCredentialsProvider.create(builder.build());
115+
}
89116
```
90117

91118
### Configuration for a managed identity {#mgd-identity}
@@ -97,75 +124,96 @@ For a system assigned managed identity, simply add the `systemAssignedManagedIde
97124
method to the `EntraIDTokenAuthConfigBuilder` chain:
98125

99126
```java
100-
TokenAuthConfig authConfig = EntraIDTokenAuthConfigBuilder.builder()
101-
.systemAssignedManagedIdentity()
102-
// ...
103-
.build();
127+
TokenBasedRedisCredentialsProvider credentials;
128+
129+
try ( EntraIDTokenAuthConfigBuilder builder = EntraIDTokenAuthConfigBuilder.builder()) {
130+
builder.clientId(CLIENT_ID)
131+
// ...
132+
.systemAssignedManagedIdentity();
133+
134+
credentials = TokenBasedRedisCredentialsProvider.create(builder.build());
135+
}
104136
```
105137

106138
For a user assigned managed identity, add `userAssignedManagedIdentity()`. This
107139
requires a member of the `UserManagedIdentityType` enum (to select a
108140
`CLIENT_ID`, `OBJECT_ID`, or `RESOURCE_ID`) as well as the `id` string itself:
109141

110142
```java
111-
TokenAuthConfig authConfig = EntraIDTokenAuthConfigBuilder.builder()
112-
.userAssignedManagedIdentity(
113-
UserManagedIdentityType.CLIENT_ID,
114-
"<ID>"
115-
)
116-
// ...
117-
.build();
118-
143+
TokenBasedRedisCredentialsProvider credentials;
144+
145+
try ( EntraIDTokenAuthConfigBuilder builder = EntraIDTokenAuthConfigBuilder.builder()) {
146+
builder.clientId(CLIENT_ID)
147+
// ...
148+
.userAssignedManagedIdentity(
149+
UserManagedIdentityType.CLIENT_ID,
150+
"<ID>"
151+
);
152+
153+
credentials = TokenBasedRedisCredentialsProvider.create(builder.build());
154+
}
119155
```
120156

121157
## Connect using the `withAuthentication()` option
122158

123-
When you have created your `TokenAuthConfig` instance, you are ready to
159+
When you have created your `TokenBasedRedisCredentialsProvider` instance, you are ready to
124160
connect to AMR.
125-
The example below shows how to include the `TokenAuthConfig` details in a
161+
The example below shows how to include the authentication details in a
126162
`TokenBasedRedisCredentialsProvider` instance and pass it to the `RedisURI.Builder`
127-
using the `withAuthentication()` option.
128-
129-
{{< note >}} Azure requires you to use
130-
[Transport Layer Security (TLS)](https://en.wikipedia.org/wiki/Transport_Layer_Security)
131-
when you connect, as shown in the example.
163+
using the `withAuthentication()` option. It also uses a `ClientOptions` object to
164+
enable automatic re-authentication.
165+
166+
The connection uses
167+
[Transport Layer Security (TLS)](https://en.wikipedia.org/wiki/Transport_Layer_Security),
168+
which is recommended and enabled by default for managed identities. See
169+
[TLS connection]({{< relref "/develop/clients/lettuce/connect#tls-connection" >}}) for more information.
170+
171+
{{< note >}} The `Lettuce` client library doesn't manage the lifecycle of
172+
the `TokenBasedRedisCredentialsProvider` instance for you. You can reuse the
173+
same instance for as many clients and connections as you want. When you have
174+
finished using the credentials provider, call its `close()` method, as shown
175+
at the end of the example.
132176
{{< /note >}}
133177

134178
```java
135-
TokenAuthConfig authConfig = EntraIDTokenAuthConfigBuilder.builder()
136-
// Chain of options...
137-
.build();
138-
139-
TokenBasedRedisCredentialsProvider credentialsProvider =
140-
TokenBasedRedisCredentialsProvider.create(tokenAuthConfig);
141-
142-
RedisURI uri = RedisURI.Builder.redis("<host>", <port>)
143-
.withAuthentication(credentialsProvider)
179+
// Entra ID credentials provider for Service Principal Identity with Client Secret.
180+
TokenBasedRedisCredentialsProvider credentialsSP;
181+
try (EntraIDTokenAuthConfigBuilder builder = EntraIDTokenAuthConfigBuilder.builder()) {
182+
builder
183+
.clientId(CLIENT_ID)
184+
.secret(CLIENT_SECRET).authority(AUTHORITY) // "https://login.microsoftonline.com/{YOUR_TENANT_ID}"
185+
.scopes(SCOPES); // "https://redis.azure.com/.default"
186+
187+
credentialsSP = TokenBasedRedisCredentialsProvider.create(builder.build());
188+
}
189+
190+
// Optionally test the credentials provider.
191+
// credentialsSP.resolveCredentials().doOnNext(c -> System.out.println("SPI ID :" + c.getUsername())).block();
192+
193+
// Enable automatic re-authentication.
194+
ClientOptions clientOptions = ClientOptions.builder()
195+
.reauthenticateBehavior(
196+
ClientOptions.ReauthenticateBehavior.ON_NEW_CREDENTIALS
197+
).build();
198+
199+
// Use the Entra ID credentials provider.
200+
RedisURI redisURI = RedisURI.builder()
201+
.withHost(HOST)
202+
.withPort(PORT)
203+
.withAuthentication(credentialsSP)
144204
.withSsl(true)
145205
.build();
146206

147-
RedisClient client = RedisClient.create(uri);
148-
149-
SslOptions sslOptions = SslOptions.builder().jdkSslProvider()
150-
.truststore(new File(
151-
"<path_to_truststore.jks_file>"),
152-
"<password_for_truststore.jks_file>"
153-
)
154-
.build();
155-
156-
client.setOptions(ClientOptions.builder()
157-
.sslOptions(sslOptions)
158-
.build());
159-
160-
StatefulRedisConnection<String, String> connection = client.connect();
161-
RedisAsyncCommands<String, String> asyncCommands = connection.async();
162-
163-
// Test the connection.
164-
CompletableFuture<Void> testDBSize = asyncCommands.dbsize()
165-
.thenAccept(r -> {
166-
System.out.println(String.format("Database size: %d", r));
167-
})
168-
.toCompletableFuture();
169-
170-
testDBSize.join();
207+
// Create the RedisClient and set the re-authentication options.
208+
RedisClient redisClient = RedisClient.create(redisURI);
209+
redisClient.setOptions(clientOptions);
210+
211+
// Connect with the credentials provider.
212+
try (StatefulRedisConnection<String, String> user1 = redisClient.connect(StringCodec.UTF8)) {
213+
System.out.println("Connected to redis as :" + user1.sync().aclWhoami());
214+
System.out.println("Db size :" + user1.sync().dbsize());
215+
} finally {
216+
redisClient.shutdown(); // Shutdown Redis client and close connections.
217+
credentialsSP.close(); // Shutdown Entra ID Credentials provider.
218+
}
171219
```

0 commit comments

Comments
 (0)