45
45
import javax .naming .AuthenticationException ;
46
46
import javax .net .ssl .SSLSession ;
47
47
import lombok .Getter ;
48
+ import org .apache .pulsar .PulsarVersion ;
48
49
import org .apache .pulsar .broker .PulsarServerException ;
49
50
import org .apache .pulsar .broker .authentication .AuthenticationDataSource ;
50
51
import org .apache .pulsar .broker .authentication .AuthenticationProvider ;
@@ -316,12 +317,13 @@ private synchronized void completeConnect(AuthData clientData) throws PulsarClie
316
317
this .clientAuthData = clientData ;
317
318
this .clientAuthMethod = authMethod ;
318
319
}
319
- clientCnxSupplier =
320
- () -> new ProxyClientCnx (clientConf , service .getWorkerGroup (), clientAuthRole , clientAuthData ,
321
- clientAuthMethod , protocolVersionToAdvertise );
320
+ clientCnxSupplier = () -> new ProxyClientCnx (clientConf , service .getWorkerGroup (), clientAuthRole ,
321
+ clientAuthData ,
322
+ this ::requestRefreshClientAuthData ,
323
+ clientAuthMethod , protocolVersionToAdvertise ,
324
+ service .getConfiguration ().isForwardAuthorizationCredentials ());
322
325
} else {
323
- clientCnxSupplier =
324
- () -> new ClientCnx (clientConf , service .getWorkerGroup (), protocolVersionToAdvertise );
326
+ clientCnxSupplier = () -> new ClientCnx (clientConf , service .getWorkerGroup (), protocolVersionToAdvertise );
325
327
}
326
328
327
329
if (this .connectionPool == null ) {
@@ -423,16 +425,22 @@ public void brokerConnected(DirectProxyHandler directProxyHandler, CommandConnec
423
425
}
424
426
425
427
// According to auth result, send newConnected or newAuthChallenge command.
426
- private void doAuthentication (AuthData clientData ) throws Exception {
428
+ private void doAuthentication (AuthData clientData )
429
+ throws Exception {
427
430
AuthData brokerData = authState .authenticate (clientData );
428
431
// authentication has completed, will send newConnected command.
429
432
if (authState .isComplete ()) {
430
433
clientAuthRole = authState .getAuthRole ();
431
434
if (LOG .isDebugEnabled ()) {
432
435
LOG .debug ("[{}] Client successfully authenticated with {} role {}" ,
433
- remoteAddress , authMethod , clientAuthRole );
436
+ remoteAddress , authMethod , clientAuthRole );
437
+ }
438
+
439
+ // First connection
440
+ if (this .connectionPool == null || state == State .Connecting ) {
441
+ // authentication has completed, will send newConnected command.
442
+ completeConnect (clientData );
434
443
}
435
- completeConnect (clientData );
436
444
return ;
437
445
}
438
446
@@ -441,7 +449,7 @@ private void doAuthentication(AuthData clientData) throws Exception {
441
449
.addListener (ChannelFutureListener .FIRE_EXCEPTION_ON_FAILURE );
442
450
if (LOG .isDebugEnabled ()) {
443
451
LOG .debug ("[{}] Authentication in progress client by method {}." ,
444
- remoteAddress , authMethod );
452
+ remoteAddress , authMethod );
445
453
}
446
454
state = State .Connecting ;
447
455
}
@@ -523,7 +531,6 @@ remoteAddress, protocolVersionToAdvertise, getRemoteEndpointProtocolVersion(),
523
531
524
532
@ Override
525
533
protected void handleAuthResponse (CommandAuthResponse authResponse ) {
526
- checkArgument (state == State .Connecting );
527
534
checkArgument (authResponse .hasResponse ());
528
535
checkArgument (authResponse .getResponse ().hasAuthData () && authResponse .getResponse ().hasAuthMethodName ());
529
536
@@ -535,6 +542,53 @@ protected void handleAuthResponse(CommandAuthResponse authResponse) {
535
542
try {
536
543
AuthData clientData = AuthData .of (authResponse .getResponse ().getAuthData ());
537
544
doAuthentication (clientData );
545
+ if (connectionPool != null && state == State .ProxyLookupRequests ) {
546
+ if (service .getConfiguration ().isForwardAuthorizationCredentials ()) {
547
+ connectionPool .getConnections ().forEach (toBrokerCnxFuture -> {
548
+ String clientVersion ;
549
+ if (authResponse .hasClientVersion ()) {
550
+ clientVersion = authResponse .getClientVersion ();
551
+ } else {
552
+ clientVersion = PulsarVersion .getVersion ();
553
+ }
554
+ int protocolVersion ;
555
+ if (authResponse .hasProtocolVersion ()) {
556
+ protocolVersion = authResponse .getProtocolVersion ();
557
+ } else {
558
+ protocolVersion = Commands .getCurrentProtocolVersion ();
559
+ }
560
+
561
+ ByteBuf cmd =
562
+ Commands .newAuthResponse (clientAuthMethod , clientData , protocolVersion , clientVersion );
563
+ toBrokerCnxFuture .thenAccept (toBrokerCnx -> toBrokerCnx .ctx ().writeAndFlush (cmd )
564
+ .addListener (writeFuture -> {
565
+ if (writeFuture .isSuccess ()) {
566
+ if (LOG .isDebugEnabled ()) {
567
+ LOG .debug ("{} authentication is refreshed successfully by {}" +
568
+ ", auth method: {} " ,
569
+ toBrokerCnx .ctx ().channel (), ctx .channel (), clientAuthMethod );
570
+ }
571
+ } else {
572
+ LOG .error ("Failed to forward the auth response command "
573
+ + "from the proxy to the broker through the proxy client, "
574
+ + "proxy: {}, proxy client: {}" ,
575
+ ctx .channel (),
576
+ toBrokerCnx .ctx ().channel (),
577
+ writeFuture .cause ());
578
+ toBrokerCnx .ctx ().channel ().pipeline ().fireExceptionCaught (writeFuture .cause ());
579
+ }
580
+ }))
581
+ .whenComplete ((__ , ex ) -> {
582
+ if (ex != null ) {
583
+ LOG .error ("Failed to forward the auth response command "
584
+ + "from the proxy to the broker through the proxy client, "
585
+ + "proxy: {}" ,
586
+ ctx ().channel (), ex );
587
+ }
588
+ });
589
+ });
590
+ }
591
+ }
538
592
} catch (Exception e ) {
539
593
String msg = "Unable to handleAuthResponse" ;
540
594
LOG .warn ("[{}] {} " , remoteAddress , msg , e );
@@ -543,6 +597,23 @@ protected void handleAuthResponse(CommandAuthResponse authResponse) {
543
597
}
544
598
}
545
599
600
+ private void requestRefreshClientAuthData () {
601
+ ctx .writeAndFlush (Commands .newAuthChallenge (clientAuthMethod , AuthData .REFRESH_AUTH_DATA ,
602
+ protocolVersionToAdvertise ))
603
+ .addListener (writeFuture -> {
604
+ if (writeFuture .isSuccess ()) {
605
+ if (LOG .isDebugEnabled ()) {
606
+ LOG .debug ("{} Sent auth challenge to client to refresh credentials with method: {}" ,
607
+ ctx .channel (), clientAuthMethod );
608
+ }
609
+ } else {
610
+ LOG .error ("{} Failed to send request for mutual auth to client" , ctx .channel (),
611
+ writeFuture .cause ());
612
+ ctx .channel ().pipeline ().fireExceptionCaught (writeFuture .cause ());
613
+ }
614
+ });
615
+ }
616
+
546
617
@ Override
547
618
protected void handlePartitionMetadataRequest (CommandPartitionedTopicMetadata partitionMetadata ) {
548
619
checkArgument (state == State .ProxyLookupRequests );
0 commit comments