@@ -24,6 +24,10 @@ You can authenticate using a system-assigned or user-assigned
2424or a [ service principal] ( https://learn.microsoft.com/en-us/entra/identity-platform/app-objects-and-service-principals ) ,
2525letting ` 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
2933Install [ ` Lettuce ` ] ({{< relref "/develop/clients/lettuce" >}}) first,
@@ -47,19 +51,24 @@ If you are using Gradle, add the following dependency to your
4751implementation ' 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
5357must supply when you connect to Redis. Chain the methods of the
5458` EntraIDTokenAuthConfigBuilder ` class together (starting with the ` builder() `
5559method) 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
6574Some 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
7384You can also add configuration to authenticate with a [ service principal] ( #serv-principal )
7485or 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
7899Add ` clientId() ` to the ` EntraIDTokenAuthConfigBuilder ` chain to specify
@@ -82,10 +103,16 @@ a parameter. (See the
82103for 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
97124method 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
106138For a user assigned managed identity, add ` userAssignedManagedIdentity() ` . This
107139requires 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
124160connect 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