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,11 @@ 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 , clientAuthMethod , protocolVersionToAdvertise ,
322
+ service . getConfiguration (). isForwardAuthorizationCredentials (), this );
322
323
} else {
323
- clientCnxSupplier =
324
- () -> new ClientCnx (clientConf , service .getWorkerGroup (), protocolVersionToAdvertise );
324
+ clientCnxSupplier = () -> new ClientCnx (clientConf , service .getWorkerGroup (), protocolVersionToAdvertise );
325
325
}
326
326
327
327
if (this .connectionPool == null ) {
@@ -423,16 +423,22 @@ public void brokerConnected(DirectProxyHandler directProxyHandler, CommandConnec
423
423
}
424
424
425
425
// According to auth result, send newConnected or newAuthChallenge command.
426
- private void doAuthentication (AuthData clientData ) throws Exception {
426
+ private void doAuthentication (AuthData clientData )
427
+ throws Exception {
427
428
AuthData brokerData = authState .authenticate (clientData );
428
429
// authentication has completed, will send newConnected command.
429
430
if (authState .isComplete ()) {
430
431
clientAuthRole = authState .getAuthRole ();
431
432
if (LOG .isDebugEnabled ()) {
432
433
LOG .debug ("[{}] Client successfully authenticated with {} role {}" ,
433
- remoteAddress , authMethod , clientAuthRole );
434
+ remoteAddress , authMethod , clientAuthRole );
435
+ }
436
+
437
+ // First connection
438
+ if (this .connectionPool == null || state == State .Connecting ) {
439
+ // authentication has completed, will send newConnected command.
440
+ completeConnect (clientData );
434
441
}
435
- completeConnect (clientData );
436
442
return ;
437
443
}
438
444
@@ -441,7 +447,7 @@ private void doAuthentication(AuthData clientData) throws Exception {
441
447
.addListener (ChannelFutureListener .FIRE_EXCEPTION_ON_FAILURE );
442
448
if (LOG .isDebugEnabled ()) {
443
449
LOG .debug ("[{}] Authentication in progress client by method {}." ,
444
- remoteAddress , authMethod );
450
+ remoteAddress , authMethod );
445
451
}
446
452
state = State .Connecting ;
447
453
}
@@ -523,18 +529,63 @@ remoteAddress, protocolVersionToAdvertise, getRemoteEndpointProtocolVersion(),
523
529
524
530
@ Override
525
531
protected void handleAuthResponse (CommandAuthResponse authResponse ) {
526
- checkArgument (state == State .Connecting );
527
532
checkArgument (authResponse .hasResponse ());
528
533
checkArgument (authResponse .getResponse ().hasAuthData () && authResponse .getResponse ().hasAuthMethodName ());
529
534
530
535
if (LOG .isDebugEnabled ()) {
531
536
LOG .debug ("Received AuthResponse from {}, auth method: {}" ,
532
- remoteAddress , authResponse .getResponse ().getAuthMethodName ());
537
+ remoteAddress , authResponse .getResponse ().getAuthMethodName ());
533
538
}
534
539
535
540
try {
536
541
AuthData clientData = AuthData .of (authResponse .getResponse ().getAuthData ());
537
542
doAuthentication (clientData );
543
+ if (service .getConfiguration ().isForwardAuthorizationCredentials ()
544
+ && connectionPool != null && state == State .ProxyLookupRequests ) {
545
+ connectionPool .getConnections ().forEach (toBrokerCnxFuture -> {
546
+ String clientVersion ;
547
+ if (authResponse .hasClientVersion ()) {
548
+ clientVersion = authResponse .getClientVersion ();
549
+ } else {
550
+ clientVersion = PulsarVersion .getVersion ();
551
+ }
552
+ int protocolVersion ;
553
+ if (authResponse .hasProtocolVersion ()) {
554
+ protocolVersion = authResponse .getProtocolVersion ();
555
+ } else {
556
+ protocolVersion = Commands .getCurrentProtocolVersion ();
557
+ }
558
+
559
+ ByteBuf cmd =
560
+ Commands .newAuthResponse (clientAuthMethod , clientData , protocolVersion , clientVersion );
561
+ toBrokerCnxFuture .thenAccept (toBrokerCnx -> toBrokerCnx .ctx ().writeAndFlush (cmd )
562
+ .addListener (writeFuture -> {
563
+ if (writeFuture .isSuccess ()) {
564
+ if (LOG .isDebugEnabled ()) {
565
+ LOG .debug ("{} authentication is refreshed successfully by {}, "
566
+ + "auth method: {} " ,
567
+ toBrokerCnx .ctx ().channel (), ctx .channel (), clientAuthMethod );
568
+ }
569
+ } else {
570
+ LOG .error ("Failed to forward the auth response "
571
+ + "from the proxy to the broker through the proxy client, "
572
+ + "proxy: {}, proxy client: {}" ,
573
+ ctx .channel (),
574
+ toBrokerCnx .ctx ().channel (),
575
+ writeFuture .cause ());
576
+ toBrokerCnx .ctx ().channel ().pipeline ()
577
+ .fireExceptionCaught (writeFuture .cause ());
578
+ }
579
+ }))
580
+ .whenComplete ((__ , ex ) -> {
581
+ if (ex != null ) {
582
+ LOG .error ("Failed to forward the auth response from the proxy to "
583
+ + "the broker through the proxy client, proxy: {}" ,
584
+ ctx ().channel (), ex );
585
+ }
586
+ });
587
+ });
588
+ }
538
589
} catch (Exception e ) {
539
590
String msg = "Unable to handleAuthResponse" ;
540
591
LOG .warn ("[{}] {} " , remoteAddress , msg , e );
0 commit comments