Skip to content

[Issue 10816][Proxy] Refresh client auth token - #13339

Closed
kkoderok wants to merge 1 commit into
apache:masterfrom
kkoderok:fix-10816
Closed

[Issue 10816][Proxy] Refresh client auth token#13339
kkoderok wants to merge 1 commit into
apache:masterfrom
kkoderok:fix-10816

Conversation

@kkoderok

Copy link
Copy Markdown

Fixes #10816

Motivation

See #10816

Modifications

Refresh client token on proxy (to lookup) in case when refresh token command have been received from broker.

Verifying this change

  • Make sure that the change passes the CI checks.

This change added tests and can be verified as follows:

  • org.apache.pulsar.proxy.server.ProxyWithJwtAuthorizationTest#testRefreshClientToken

Does this pull request potentially affect one of the following parts:

If yes was chosen, please highlight the changes

  • Dependencies (does it add or upgrade a dependency): (no)
  • The public API: (no)
  • The schema: (no)
  • The default values of configurations: (no)
  • The wire protocol: (no)
  • The rest endpoints: (no)
  • The admin cli options: (no)
  • Anything that affects deployment: (no)

Documentation

Check the box below and label this PR (if you have committer privilege).

Need to update docs?

  • no-need-doc
    Bug fix

@github-actions github-actions Bot added the doc-not-needed Your PR changes do not impact docs label Dec 15, 2021
@hezhangjian

Copy link
Copy Markdown
Member

@KKKoder I think you do too much checkstyle format in this PR. I would suggest to split them if needed

@hezhangjian

Copy link
Copy Markdown
Member

@KKKoder let me open a PR for checkstyle fix

@kkoderok

Copy link
Copy Markdown
Author

@KKKoder let me open a PR for checkstyle fix

Ok, do it.

@hezhangjian

Copy link
Copy Markdown
Member

@KKKoder I have done in #13343, could you please pull master code, and undo the format, thanks :)

@github-actions

Copy link
Copy Markdown

The pr had no activity for 30 days, mark with Stale label.

.forEach(future -> future.complete(clientData));
}

private CompletableFuture<AuthData> getOrRefreshClientAuthData() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you walk me through what this method suppose to do? Thanks

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When client auth data expired and proxy configured with forward authentication data, then this method requests a new token. This method is thread safe, because one ProxyConnection has multiple ProxyClientCnx, and potentially at same time, they request
auth data.

AuthData authData = authenticationDataProvider.authenticate(AuthData.INIT_AUTH_DATA);
return Commands.newConnect(authentication.getAuthMethodName(), authData, this.protocolVersion,
PulsarVersion.getVersion(), proxyToTargetBrokerAddress, null, null, null);
return CompletableFuture.completedFuture(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the point of using CompletableFuture here ? It seems there is no async operations.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point

@kkoderok kkoderok Apr 4, 2022

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is overridden in the ProxyClientCnx class, which can use the asynchronous operation of obtaining authorization data from the client, so this method returns a CompletableFuture

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done some changes, check them please.

AuthData authData = authenticationDataProvider.authenticate(AuthData.INIT_AUTH_DATA);
return Commands.newConnect(authentication.getAuthMethodName(), authData, this.protocolVersion,
PulsarVersion.getVersion(), proxyToTargetBrokerAddress, null, null, null);
return CompletableFuture.completedFuture(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point

try {
clientAuthDataSupplier.get()
.thenAccept(authData -> sendAuthResponse(authData, clientAuthMethod));
} catch (Exception e) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how is it possible to have an Exception here ?
in case of failure we should deal with the error and send a response or close the connection

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. I will fix.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've already fixed it, make a review please.

Comment on lines +377 to +416
@Test
void testRefreshClientToken() throws Exception {
log.info("-- Starting {} test --", methodName);

startProxy();
createAdminClient();

@SuppressWarnings("unchecked")
Supplier<String> tokenSupplier = Mockito.mock(Supplier.class);
when(tokenSupplier.get()).thenAnswer(answer -> createClientJwtToken(Duration.ofSeconds(1)));

PulsarClient proxyClient = PulsarClient.builder()
.serviceUrl(proxyService.getServiceUrl()).statsInterval(0, TimeUnit.SECONDS)
.authentication(AuthenticationFactory.token(tokenSupplier))
.operationTimeout(1000, TimeUnit.MILLISECONDS)
.build();

String namespaceName = "my-property/proxy-authorization/my-ns";
admin.clusters().createCluster("proxy-authorization", ClusterData.builder().serviceUrl(brokerUrl.toString()).build());
admin.tenants().createTenant("my-property",
new TenantInfoImpl(Sets.newHashSet("appid1", "appid2"), Sets.newHashSet("proxy-authorization")));
admin.namespaces().createNamespace(namespaceName);

admin.namespaces().grantPermissionOnNamespace(namespaceName, CLIENT_ROLE,
Sets.newHashSet(AuthAction.consume, AuthAction.produce));
log.info("-- Admin permissions {} ---", admin.namespaces().getPermissions(namespaceName));

Producer<byte[]> producer = proxyClient.newProducer(Schema.BYTES)
.topic("persistent://my-property/proxy-authorization/my-ns/my-topic1").create();

final int msgs = 10;
for (int i = 0; i < msgs; i++) {
String message = "my-message-" + i;
producer.send(message.getBytes());
}

//noinspection unchecked
clearInvocations(tokenSupplier);
Thread.sleep(3000);
verify(tokenSupplier, atLeastOnce()).get();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this test is correct. It is passing for us, even without the associated fix.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. thanks. I'll check and fix the test

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made another test, check please.

@github-actions

Copy link
Copy Markdown

The pr had no activity for 30 days, mark with Stale label.

@github-actions github-actions Bot added the Stale label May 30, 2022
@nodece
nodece self-requested a review August 11, 2022 09:14
@nodece nodece self-assigned this Aug 11, 2022
@nodece

nodece commented Aug 11, 2022

Copy link
Copy Markdown
Member

Hi @kkoderok, thanks for your contribution! Can you still work on this PR? If you don't have time, I will work on this PR.

@nodece

nodece commented Sep 29, 2022

Copy link
Copy Markdown
Member

Closed by #17831.

@nodece nodece closed this Sep 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

doc-not-needed Your PR changes do not impact docs lifecycle/stale Stale

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PulsarProxy does not always refresh authentication tokens received from client

7 participants