-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[KAFKA-13848] Clients remain connected after SASL re-authentication f… #12179
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -673,30 +673,26 @@ private long calcCompletionTimesAndReturnSessionLifetimeMs() { | |
| Long credentialExpirationMs = (Long) saslServer | ||
| .getNegotiatedProperty(SaslInternalConfigs.CREDENTIAL_LIFETIME_MS_SASL_NEGOTIATED_PROPERTY_KEY); | ||
| Long connectionsMaxReauthMs = connectionsMaxReauthMsByMechanism.get(saslMechanism); | ||
| if (credentialExpirationMs != null || connectionsMaxReauthMs != null) { | ||
| boolean maxReauthSet = connectionsMaxReauthMs != null && connectionsMaxReauthMs > 0; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Make sense to me.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you! Some tests are failing on my machine also but pass when I run them in the IDE. :( Might be some flakiness but I'm looking into it right now. |
||
|
|
||
| if (credentialExpirationMs != null || maxReauthSet) { | ||
| if (credentialExpirationMs == null) | ||
| retvalSessionLifetimeMs = zeroIfNegative(connectionsMaxReauthMs); | ||
| else if (connectionsMaxReauthMs == null) | ||
| else if (!maxReauthSet) | ||
| retvalSessionLifetimeMs = zeroIfNegative(credentialExpirationMs - authenticationEndMs); | ||
| else | ||
| retvalSessionLifetimeMs = zeroIfNegative( | ||
| Math.min(credentialExpirationMs - authenticationEndMs, connectionsMaxReauthMs)); | ||
| if (retvalSessionLifetimeMs > 0L) | ||
| sessionExpirationTimeNanos = authenticationEndNanos + 1000 * 1000 * retvalSessionLifetimeMs; | ||
| retvalSessionLifetimeMs = zeroIfNegative(Math.min(credentialExpirationMs - authenticationEndMs, connectionsMaxReauthMs)); | ||
|
|
||
| sessionExpirationTimeNanos = authenticationEndNanos + 1000 * 1000 * retvalSessionLifetimeMs; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably worth a comment explaining that
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After some investigation, I found the So, maybe here, we should make sure we need re-auth (that is, we did have expiration time, if it's 0, which means it's expired, not re-auth disabled). ex: if (retvalSessionLifetimeMs > 0L || credentialExpirationMs != null || connectionsMaxReauthMs != null)
sessionExpirationTimeNanos = authenticationEndNanos + 1000 * 1000 * retvalSessionLifetimeMs;So, if the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding I think the correct fix is to delay the initialisation of |
||
| } | ||
|
|
||
| if (credentialExpirationMs != null) { | ||
| if (sessionExpirationTimeNanos != null) | ||
| LOG.debug( | ||
| "Authentication complete; session max lifetime from broker config={} ms, credential expiration={} ({} ms); session expiration = {} ({} ms), sending {} ms to client", | ||
| connectionsMaxReauthMs, new Date(credentialExpirationMs), | ||
| credentialExpirationMs - authenticationEndMs, | ||
| new Date(authenticationEndMs + retvalSessionLifetimeMs), retvalSessionLifetimeMs, | ||
| retvalSessionLifetimeMs); | ||
| else | ||
| LOG.debug( | ||
| "Authentication complete; session max lifetime from broker config={} ms, credential expiration={} ({} ms); no session expiration, sending 0 ms to client", | ||
| connectionsMaxReauthMs, new Date(credentialExpirationMs), | ||
| credentialExpirationMs - authenticationEndMs); | ||
| LOG.debug( | ||
| "Authentication complete; session max lifetime from broker config={} ms, credential expiration={} ({} ms); session expiration = {} ({} ms), sending {} ms to client", | ||
| connectionsMaxReauthMs, new Date(credentialExpirationMs), | ||
| credentialExpirationMs - authenticationEndMs, | ||
| new Date(authenticationEndMs + retvalSessionLifetimeMs), retvalSessionLifetimeMs, | ||
| retvalSessionLifetimeMs); | ||
| } else { | ||
| if (sessionExpirationTimeNanos != null) | ||
| LOG.debug( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -781,14 +781,13 @@ public void testConnectDisconnectDuringInSinglePoll() throws Exception { | |
| when(kafkaChannel.selectionKey()).thenReturn(selectionKey); | ||
| when(selectionKey.channel()).thenReturn(SocketChannel.open()); | ||
| when(selectionKey.readyOps()).thenReturn(SelectionKey.OP_CONNECT); | ||
| when(selectionKey.attachment()).thenReturn(kafkaChannel); | ||
|
|
||
| selectionKey.attach(kafkaChannel); | ||
| Set<SelectionKey> selectionKeys = Utils.mkSet(selectionKey); | ||
| selector.pollSelectionKeys(selectionKeys, false, System.nanoTime()); | ||
|
|
||
| assertFalse(selector.connected().contains(kafkaChannel.id())); | ||
| assertTrue(selector.disconnected().containsKey(kafkaChannel.id())); | ||
| assertNull(selectionKey.attachment()); | ||
|
Comment on lines
+784
to
-791
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why we did this change? Did we change anything affect this test?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test failed after my change to use mockitoInline to mock statics. The
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the explanation. I agree with the change. Make sense. |
||
|
|
||
| verify(kafkaChannel, atLeastOnce()).ready(); | ||
| verify(kafkaChannel).disconnect(); | ||
|
|
@@ -976,8 +975,11 @@ public void testChannelCloseWhileProcessingReceives() throws Exception { | |
| SelectionKey selectionKey = mock(SelectionKey.class); | ||
| when(channel.selectionKey()).thenReturn(selectionKey); | ||
| when(selectionKey.isValid()).thenReturn(true); | ||
| when(selectionKey.isReadable()).thenReturn(true); | ||
| when(selectionKey.readyOps()).thenReturn(SelectionKey.OP_READ); | ||
| selectionKey.attach(channel); | ||
| when(selectionKey.attachment()) | ||
| .thenReturn(channel) | ||
| .thenReturn(null); | ||
|
Comment on lines
+978
to
+982
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here, why this change?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above. |
||
| selectionKeys.add(selectionKey); | ||
|
|
||
| NetworkReceive receive = mock(NetworkReceive.class); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain why we need MockitoInline here? Any method only exists in
mockitoInline?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I needed this to mock out ChannelBuilders#createPrincipalBuilder and Sasl#createSaslServer. It's a petty there are these static calls, hard to test them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ChannelBuildersis our code, we should avoid mocking static methods.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@acsaki , as @ijuma suggested, would you file another small PR to update the tests to avoid mocking the static methods? For the
ChannelBuilders#createPrincipalBuilder, it looks like we actually don't need it for these tests, right? (the tests still pass after I removed them)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bump, I second we should aim to remove this