1414import java .util .List ;
1515import java .util .Map ;
1616import java .util .function .Supplier ;
17+ import java .util .concurrent .atomic .AtomicReference ;
1718
1819import redis .clients .jedis .Protocol .Command ;
1920import redis .clients .jedis .Protocol .Keyword ;
2021import redis .clients .jedis .annots .Experimental ;
2122import redis .clients .jedis .args .ClientAttributeOption ;
2223import redis .clients .jedis .args .Rawable ;
24+ import redis .clients .jedis .authentication .AuthXManager ;
2325import redis .clients .jedis .commands .ProtocolCommand ;
2426import redis .clients .jedis .exceptions .JedisConnectionException ;
2527import redis .clients .jedis .exceptions .JedisDataException ;
@@ -44,6 +46,8 @@ public class Connection implements Closeable {
4446 private String strVal ;
4547 protected String server ;
4648 protected String version ;
49+ private AtomicReference <RedisCredentials > currentCredentials = new AtomicReference <>(null );
50+ private AuthXManager authXManager ;
4751
4852 public Connection () {
4953 this (Protocol .DEFAULT_HOST , Protocol .DEFAULT_PORT );
@@ -63,6 +67,7 @@ public Connection(final HostAndPort hostAndPort, final JedisClientConfig clientC
6367
6468 public Connection (final JedisSocketFactory socketFactory ) {
6569 this .socketFactory = socketFactory ;
70+ this .authXManager = null ;
6671 }
6772
6873 public Connection (final JedisSocketFactory socketFactory , JedisClientConfig clientConfig ) {
@@ -93,8 +98,8 @@ public String toIdentityString() {
9398 SocketAddress remoteAddr = socket .getRemoteSocketAddress ();
9499 SocketAddress localAddr = socket .getLocalSocketAddress ();
95100 if (remoteAddr != null ) {
96- strVal = String .format ("%s{id: 0x%X, L:%s %c R:%s}" , className , id ,
97- localAddr , (broken ? '!' : '-' ), remoteAddr );
101+ strVal = String .format ("%s{id: 0x%X, L:%s %c R:%s}" , className , id , localAddr ,
102+ (broken ? '!' : '-' ), remoteAddr );
98103 } else if (localAddr != null ) {
99104 strVal = String .format ("%s{id: 0x%X, L:%s}" , className , id , localAddr );
100105 } else {
@@ -438,8 +443,8 @@ private static boolean validateClientInfo(String info) {
438443 for (int i = 0 ; i < info .length (); i ++) {
439444 char c = info .charAt (i );
440445 if (c < '!' || c > '~' ) {
441- throw new JedisValidationException ("client info cannot contain spaces, "
442- + "newlines or special characters." );
446+ throw new JedisValidationException (
447+ "client info cannot contain spaces, " + "newlines or special characters." );
443448 }
444449 }
445450 return true ;
@@ -451,7 +456,13 @@ protected void initializeFromClientConfig(final JedisClientConfig config) {
451456
452457 protocol = config .getRedisProtocol ();
453458
454- final Supplier <RedisCredentials > credentialsProvider = config .getCredentialsProvider ();
459+ Supplier <RedisCredentials > credentialsProvider = config .getCredentialsProvider ();
460+
461+ authXManager = config .getAuthXManager ();
462+ if (authXManager != null ) {
463+ credentialsProvider = authXManager ;
464+ }
465+
455466 if (credentialsProvider instanceof RedisCredentialsProvider ) {
456467 final RedisCredentialsProvider redisCredentialsProvider = (RedisCredentialsProvider ) credentialsProvider ;
457468 try {
@@ -469,7 +480,8 @@ protected void initializeFromClientConfig(final JedisClientConfig config) {
469480
470481 String clientName = config .getClientName ();
471482 if (clientName != null && validateClientInfo (clientName )) {
472- fireAndForgetMsg .add (new CommandArguments (Command .CLIENT ).add (Keyword .SETNAME ).add (clientName ));
483+ fireAndForgetMsg
484+ .add (new CommandArguments (Command .CLIENT ).add (Keyword .SETNAME ).add (clientName ));
473485 }
474486
475487 ClientSetInfoConfig setInfoConfig = config .getClientSetInfoConfig ();
@@ -525,12 +537,13 @@ private void helloAndAuth(final RedisProtocol protocol, final RedisCredentials c
525537 if (protocol != null && credentials != null && credentials .getUser () != null ) {
526538 byte [] rawPass = encodeToBytes (credentials .getPassword ());
527539 try {
528- helloResult = hello (encode (protocol .version ()), Keyword .AUTH .getRaw (), encode (credentials .getUser ()), rawPass );
540+ helloResult = hello (encode (protocol .version ()), Keyword .AUTH .getRaw (),
541+ encode (credentials .getUser ()), rawPass );
529542 } finally {
530543 Arrays .fill (rawPass , (byte ) 0 ); // clear sensitive data
531544 }
532545 } else {
533- auth (credentials );
546+ authenticate (credentials );
534547 helloResult = protocol == null ? null : hello (encode (protocol .version ()));
535548 }
536549 if (helloResult != null ) {
@@ -542,9 +555,13 @@ private void helloAndAuth(final RedisProtocol protocol, final RedisCredentials c
542555 // handled in RedisCredentialsProvider.cleanUp()
543556 }
544557
545- private void auth (RedisCredentials credentials ) {
558+ public void setCredentials (RedisCredentials credentials ) {
559+ currentCredentials .set (credentials );
560+ }
561+
562+ private String authenticate (RedisCredentials credentials ) {
546563 if (credentials == null || credentials .getPassword () == null ) {
547- return ;
564+ return null ;
548565 }
549566 byte [] rawPass = encodeToBytes (credentials .getPassword ());
550567 try {
@@ -556,7 +573,11 @@ private void auth(RedisCredentials credentials) {
556573 } finally {
557574 Arrays .fill (rawPass , (byte ) 0 ); // clear sensitive data
558575 }
559- getStatusCodeReply ();
576+ return getStatusCodeReply ();
577+ }
578+
579+ public String reAuthenticate () {
580+ return authenticate (currentCredentials .getAndSet (null ));
560581 }
561582
562583 protected Map <String , Object > hello (byte []... args ) {
@@ -585,4 +606,12 @@ public boolean ping() {
585606 }
586607 return true ;
587608 }
609+
610+ protected boolean isTokenBasedAuthenticationEnabled () {
611+ return authXManager != null ;
612+ }
613+
614+ protected AuthXManager getAuthXManager () {
615+ return authXManager ;
616+ }
588617}
0 commit comments