@@ -24,6 +24,10 @@ You can authenticate using a system-assigned or user-assigned
24
24
or a [ service principal] ( https://learn.microsoft.com/en-us/entra/identity-platform/app-objects-and-service-principals ) ,
25
25
letting ` redis-authx-entraid ` fetch and renew the authentication tokens for you automatically.
26
26
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
+
27
31
## Install
28
32
29
33
Install [ ` Lettuce ` ] ({{< relref "/develop/clients/lettuce" >}}) first,
@@ -47,19 +51,24 @@ If you are using Gradle, add the following dependency to your
47
51
implementation ' redis.clients.authentication:redis-authx-entraid:0.1.1-beta1'
48
52
```
49
53
50
- ## Create a ` TokenAuthConfig ` instance
54
+ ## Create a ` TokenBasedRedisCredentialsProvider ` instance
51
55
52
- The ` TokenAuthConfig ` class contains the authentication details that you
56
+ The ` TokenBasedRedisCredentialsProvider ` class contains the authentication details that you
53
57
must supply when you connect to Redis. Chain the methods of the
54
58
` EntraIDTokenAuthConfigBuilder ` class together (starting with the ` builder() `
55
59
method) to include the details you need, as shown in the following example:
56
60
57
61
``` 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
+ }
63
72
```
64
73
65
74
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:
68
77
- ` authority() ` : A string containing the [ authority] ( https://learn.microsoft.com/en-us/entra/identity-platform/msal-client-application-configuration#authority )
69
78
URL.
70
79
- ` 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 )
72
83
73
84
You can also add configuration to authenticate with a [ service principal] ( #serv-principal )
74
85
or a [ managed identity] ( #mgd-identity ) as described in the sections below.
75
86
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
+
76
97
### Configuration for a service principal {#serv-principal}
77
98
78
99
Add ` clientId() ` to the ` EntraIDTokenAuthConfigBuilder ` chain to specify
@@ -82,10 +103,16 @@ a parameter. (See the
82
103
for more information about service principals.)
83
104
84
105
``` 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
+ }
89
116
```
90
117
91
118
### Configuration for a managed identity {#mgd-identity}
@@ -97,75 +124,96 @@ For a system assigned managed identity, simply add the `systemAssignedManagedIde
97
124
method to the ` EntraIDTokenAuthConfigBuilder ` chain:
98
125
99
126
``` 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
+ }
104
136
```
105
137
106
138
For a user assigned managed identity, add ` userAssignedManagedIdentity() ` . This
107
139
requires a member of the ` UserManagedIdentityType ` enum (to select a
108
140
` CLIENT_ID ` , ` OBJECT_ID ` , or ` RESOURCE_ID ` ) as well as the ` id ` string itself:
109
141
110
142
``` 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
+ }
119
155
```
120
156
121
157
## Connect using the ` withAuthentication() ` option
122
158
123
- When you have created your ` TokenAuthConfig ` instance, you are ready to
159
+ When you have created your ` TokenBasedRedisCredentialsProvider ` instance, you are ready to
124
160
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
126
162
` 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.
132
176
{{< /note >}}
133
177
134
178
``` 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)
144
204
.withSsl(true )
145
205
.build();
146
206
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
+ }
171
219
```
0 commit comments