-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
[fix][broker] Fix update authentication data #18130
Conversation
Codecov Report
@@ Coverage Diff @@
## master #18130 +/- ##
=============================================
+ Coverage 34.91% 45.90% +10.98%
- Complexity 5707 17633 +11926
=============================================
Files 607 1574 +967
Lines 53396 128475 +75079
Branches 5712 14132 +8420
=============================================
+ Hits 18644 58977 +40333
- Misses 32119 63410 +31291
- Partials 2633 6088 +3455
Flags with carried forward coverage won't be shown. Click here to find out more.
|
@codelipenghui @tuteng @merlimat can you please review this PR? Looks critical for token refreshing to work as expected with proxy. |
pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java
Outdated
Show resolved
Hide resolved
pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java
Outdated
Show resolved
Hide resolved
remoteAddress, authMethod, this.authRole, originalPrincipal); | ||
} | ||
CompletableFuture<AuthData> authFuture; | ||
if (!authState.isComplete()) { |
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.
The authState can be null if state != State.Connected
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.
The authState
always non-null, you can see handleConnect()
.
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 agree with @codelipenghui, I think we need to check if authState is null here, newAuthState is implemented in the custom plugin and its return value could be null
} | ||
if (state != State.Connected) { | ||
// First time authentication is done | ||
completeConnect(clientProtocolVersion, clientVersion, enableSubscriptionPatternEvaluation); |
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.
Looks like we can move out from the thenCompose()?
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.
It seems unnecessary.
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.
We have checked if the state is connected at the beginning. But we going to check the connection is not connected again here. If we can merge them, it will make the code more easy to read.
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.
We have checked if the state is connected at the beginning.
The state == State.Connected
means doing an authentication refresh operation.
The state != State.Connected
means first authentication is done.
pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java
Outdated
Show resolved
Hide resolved
pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java
Outdated
Show resolved
Hide resolved
pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java
Show resolved
Hide resolved
pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java
Outdated
Show resolved
Hide resolved
pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java
Outdated
Show resolved
Hide resolved
dd7d9c8
to
be12f6d
Compare
} | ||
state = State.Connected; |
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.
And if we can reach here. The state should be Connected right? Why need to set to Connected again?
And we should avoid change the state in another thread. Here is executed by the callback thread for completing the authFuture
.
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.
And if we can reach here. The state should be Connected right? Why need to set to Connected again?
You are right., For auth challenge multiple times, we still need to set to Conected, see line 764.
And we should avoid change the state in another thread. Here is executed by the callback thread for completing the authFuture.
Do you mean I should switch to Pulsar thread to change the state?
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.
And we should avoid change the state in another thread. Here is executed by the callback thread for completing the authFuture.
This is safe, each connection has its own ServerCnx.java, don't warry.
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 believe @codelipenghui is right here. We are updating the state from a callback which could be another thread, and that is not a safe operation here. Instead, I think we should remove all of the async references in this PR and just focus on fixing the underlying problem with authentication data. I already started work on implementing PIP 97, and I will follow up on this PR to replace the synchronous methods with asynchronous calls.
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 would like to know why this is not a safe operation. Are you worried that some other handler will change this state?
I think we should remove all of the async references in this PR and just focus on fixing the underlying problem with authentication data.
Good point out.
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.
Thanks for your PR and explanation @nodece! I would like to clarify our authn/authz design before discussing the implementation of this change.
The authorization provider cannot get the correct authentication data.
Is authentication data supposed to dynamically change? We require the role to stay the same across authentication refreshes, which implies to me that the rest of the data is supposed to be static. That might not be how it is used, in practice, though.
The primary benefit of requiring the authentication data to remain static for the given session is that it means currently authorized tasks do not need to be re-authorized. This is relevant since we do not re-verify if a role has permission to produce to a topic when we re-authenticate the client's auth data.
I'll concede that revoked permission granted to a role is not handled by our authorization scheme, but that seems like a separate question.
The validity of the authentication data is not checked.
Why do we need to verify the originalAuthenticationData
? I thought the point was that the authenticationData
had to be authentic and had to be associated to a sufficiently powerful role, and then we "trusted" the originalAuthenticationData
implicitly while using the originalAuthenticationData
for authorization purposes.
Let me know what you think. Thanks!
Yes, we can dynamically change the authentication data by auth challenge.
Usually, the authentication data need to change when the authentication data expired. Some authentication provider only care the authentication data, which didn't use a passing role by the Pulsar.
The We have two authentication data, one from the proxy, and one from the client. When the authentication has an expired limit, the authentication flow is complex, and causes some authentication issues. |
My point is that the authorization related data should not change. Auth refresh requires that some portion of the auth data changes, but because we verify that the
My understanding is that the proxy verifies the authenticity of the
It seems like your concern is not just the authentication flow, but how it interacts with authorization. Is that correct? |
Right! For the default authentication provider, which doesn't care about the authentication data. But when we implement a customize authentication provider, I depend on the authentication data, but the Pulsar cannot pass the correct authentication data to this authentication provider. |
Makes sense. My point is that we close the connection when the role changes: pulsar/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java Lines 728 to 734 in b0945d1
That logic was put in place before the logic to pass the authData to the |
It looks like we cannot update the role. Let us continue to keep this logic. pulsar/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java Lines 728 to 734 in b0945d1
Good catch, I can move this logic. |
2c87e7c
to
c60b95b
Compare
@codelipenghui @michaeljmarshall @Technoboy- Could you review this PR? Thanks for your time! |
c60b95b
to
def9d39
Compare
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.
Overall, I think that my initial criticism of this PR was based on a flawed understanding of the ServerCnx
and how forwarding authData
works. I just started work today on finishing PIP 97. I will review the code while completing that work, and that should help me give a more accurate review of this PR.
} | ||
CompletableFuture<AuthData> authFuture = CompletableFuture.completedFuture(null); | ||
if (!useOriginalAuthState && !authState.isComplete()) { | ||
authFuture = authState.authenticateAsync(clientData); |
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 am starting work on finishing PIP 97 today. I think it might make sense to remove this update to use authenticateAsync
since it is not related to this PR.
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.
This PR is to fix the correct persistence authentication state and data.
Do you want to remove which?
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.
We must use the authenticateAsync
, this is used to check the user permission.
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 am saying we should not make the switch to be asynchronous in this PR. We should make the switch in a separate PR. I started work this week to complete the PIP 97, which introduced the async changes.
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.
Done.
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.
Ping @michaeljmarshall
Signed-off-by: Zixuan Liu <nodeces@gmail.com>
Signed-off-by: Zixuan Liu <nodeces@gmail.com>
def9d39
to
357035f
Compare
Signed-off-by: Zixuan Liu <nodeces@gmail.com>
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.
@nodece - I have some questions about the underlying problem, I left some questions in comments. Otherwise, I see that there are not any new tests to cover this change. Given that it is a bug fix, we should add a test.
} | ||
state = State.Connected; |
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 believe @codelipenghui is right here. We are updating the state from a callback which could be another thread, and that is not a safe operation here. Instead, I think we should remove all of the async references in this PR and just focus on fixing the underlying problem with authentication data. I already started work on implementing PIP 97, and I will follow up on this PR to replace the synchronous methods with asynchronous calls.
// credentials, but we only can new an authentication state, because some authentication data(TLS, SASL) | ||
// based on outside service. |
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.
Can you explain this a bit more? In the case of TLS authentication, we are not able to refresh the originalAuthenticationState
, that case seems unrelated.
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.
Sorry, there is some confusion. For originalAuthentication
, we don't call the authentication checks. Because there is some state in the AuthenticationState
, which depends on outside service.
Lines 64 to 67 in 82237d3
@Override | |
public AuthData authenticate(AuthData authData) throws AuthenticationException { | |
return pulsarSaslServer.response(authData); | |
} |
originalAuthentication
belongs to the user's client by the proxy forwarded, see
pulsar/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyClientCnx.java
Lines 68 to 70 in f360807
return Commands.newConnect(authentication.getAuthMethodName(), authData, protocolVersion, | |
PulsarVersion.getVersion(), proxyToTargetBrokerAddress, clientAuthRole, clientAuthData, | |
clientAuthMethod); |
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.
For
originalAuthentication
, we don't call the authentication checks.
Isn't this a problem though? We aren't really authenticating the originalAuthData
if we don't call the authenticate
method and make sure authentication is "complete". In the ProxyConnectionToBroker
case, we can send back AuthChallenge
In the event that the proxy is forwarding authentication information, we can issue AuthChallenge
responses. It might not work so easily in the ProxyLookupRequests
state.
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.
For the current design, the originalAuthData
is credible by the proxy forwarding authentication data. This authentication data was completed in the proxy and then sent this authentication data to the broker, so we don't check the authentication data in the broker.
For ProxyLookupRequests
state, see #17831. I forward the AuthChallenge
command to the user's client by the ProxyClient and Proxy Server.
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.
For the current design, the
originalAuthData
is credible by the proxy forwarding authentication data. This authentication data was completed in the proxy and then sent this authentication data to the broker, so we don't check the authentication data in the broker.
My primary objection is that the setting required to enter this code block is called isAuthenticateOriginalAuthData
. Note that we are already verifying most auth data in the case that the newAuthState
method actually authenticates the data. That leaves out cases like SASL which do not authentication on AuthenticationState
initialization because it is a multi-stage auth. However, I've just realized that forwarding the authentication information will especially not work with SASL because the proxy only forwards the last AuthData
that it receives:
pulsar/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyConnection.java
Lines 426 to 440 in d6fcdb8
private void doAuthentication(AuthData clientData) | |
throws Exception { | |
AuthData brokerData = authState.authenticate(clientData); | |
// authentication has completed, will send newConnected command. | |
if (authState.isComplete()) { | |
clientAuthRole = authState.getAuthRole(); | |
if (LOG.isDebugEnabled()) { | |
LOG.debug("[{}] Client successfully authenticated with {} role {}", | |
remoteAddress, authMethod, clientAuthRole); | |
} | |
// First connection | |
if (this.connectionPool == null || state == State.Connecting) { | |
// authentication has completed, will send newConnected command. | |
completeConnect(clientData); |
This seems like a gap in the protocol where multi-staged authentication is not able to be properly processed through the proxy. However, if its a gap, that means it is something that could be improved without breaking anything.
One question is whether it would help to have a distinct stages where we first authenticate the proxy and then authenticate its original client (when configured to do so). That could help to open up the design and to make the protocol a bit clearer.
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.
This seems like a gap in the protocol where multi-staged authentication is not able to be properly processed through the proxy. However, if its a gap, that means it is something that could be improved without breaking anything.
When using the multi-staged authentication, we need to set authenticateOriginalAuthData=false
in the broker, and then it works fine, the broker just checks the proxy's authentication data.
One question is whether it would help to have a distinct stages where we first authenticate the proxy and then authenticate its original client (when configured to do so).
The protocol needs to be changed, distinguishing between client and proxy.
The authentication logic here is a bit confusing, but for the current design we need to give the correct configuration in our documentation.
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.
When using the multi-staged authentication, we need to set
authenticateOriginalAuthData=false
in the broker, and then it works fine, the broker just checks the proxy's authentication data.
I think this supports my statement that there is a gap in the protocol.
String newAuthRole = authState.getAuthRole(); | ||
|
||
// Refresh the auth data. | ||
this.authenticationData = authState.getAuthDataSource(); |
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 spent many hours working on the authentication framework code today. Below are some of my thoughts. They aren't necessarily my final opinion.
In the PR description, this line was identified as the root cause of the issue, but based on the description and on this PR, I think I see it as a symptom of a larger issue. We do not have a clear enough definition for the state transitions in the ServerCnx
class, which is essentially a finite state machine.
I want to describe part of the problem with this line of code. On the first pass through, the this.authenticationData
is set by getting it from this.authState.getAuthDataSource()
because useOriginalAuthState
is false
. Then, on subsequent AuthResponse
commands from the original client, the authenticationData
is set by getting it from this.originalAuthState.getAuthDataSource()
because useOriginalAuthState
is true
. That means the this.authenticationData
is incorrectly updated.
As a note, the broker gets AuthResponse
commands from the original client when the connection through the client is in state ProxyConnectionToBroker
. As of #17831, the broker also gets an AuthResponse
from the original client when the proxy is in state ProxyLookupRequests
with forwardAuthorizationCredentials=true
.
Otherwise, the proxy sends its own authentication information.
Here are some problems with the current solution:
- The
AuthResponse
protocol message only has one field forAuthData
, and there is no indication whether theAuthData
is for the proxy or the original client. As a consequence, the broker does not know whether to update theauthenticationData
or theoriginalAuthData
. - The implementation for
getAuthDataSource
does not always get the most recentauthenticationDataSource
SeeTokenAuthenticationState
. (I am already working on fixing this.)
Open questions:
- Can we just remove the
originalAuthState
and only keep track of oneauthState
? - Is the
AuthenticationState
object meant to last the whole lifecycle of a givenServerCnx
? In my mind, the answer is yes, but this PR says otherwise. If not, it feels odd that we have a "state" object.
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.
All of your description is correct.
- The
AuthResponse
protocol message only has one field forAuthData
, and there is no indication whether theAuthData
is for the proxy or the original client. As a consequence, the broker does not know whether to update theauthenticationData
or theoriginalAuthData
.
I started PIP a few months ago, see #17517
- Can we just remove the
originalAuthState
and only keep track of oneauthState
?
No. We must check both the originalAuthState
and authState
, if you don't check, you will overstep your authority.
- Is the
AuthenticationState
object meant to last the whole lifecycle of a givenServerCnx
? In my mind, the answer is yes, but this PR says otherwise. If not, it feels odd that we have a "state" object.
When authentication data changes, we need to renew the authentication state, and then we always get the correct data from that.
"state" is originalAuthState
or authState
.
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.
No. We must check both the
originalAuthState
andauthState
, if you don't check, you will overstep your authority.
I agree that we currently check authorization on the proxy role and the original principal as well as with the proxy's authenticationDataSource
and the originalAuthenticationDataSource
. However, I am not sure why that is necessary, and as we've discussed, this is not even done correctly for the auth data source.
What is the case that a client will overstep its authority?
When the proxy is forwarding authentication data, it seems sufficient to verify that the proxy's authentication data is valid for a proxy as a one time check during connection initialization. All subsequent auth challenges will go to the client anyway.
If the proxy is unable to forward authentication data, then the broker will only have the proxy's authentication data and the originalPrincipal
.
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.
However, I am not sure why that is necessary, and as we've discussed, this is not even done correctly for the auth data source.
For the current design, the authenticationDataSource
is credible by the proxy forwarding authentication data. This authentication data was completed in the proxy and then sent this authentication data to the broker, so we don't check the authentication data in the broker.
When the proxy is forwarding authentication data, it seems sufficient to verify that the proxy's authentication data is valid for a proxy as a one time check during connection initialization. All subsequent auth challenges will go to the client anyway.
I thought the same thing, but the Proxy's role usually is a superuser, if we don't check the client's role, this is overstepping its authority, and the client can get the lookup data and topic data.
If we don't consider this case, I agree with you.
No. We must check both the originalAuthState and authState, if you don't check, you will overstep your authority.
I agree that we currently check authorization on the proxy role and the original principal as well as with the proxy's authenticationDataSource and the originalAuthenticationDataSource. However, I am not sure why that is necessary, and as we've discussed, this is not even done correctly for the auth data source.
What is the case that a client will overstep its authority?
When the proxy is forwarding authentication data, it seems sufficient to verify that the proxy's authentication data is valid for a proxy as a one time check during connection initialization. All subsequent auth challenges will go to the client anyway.
If the proxy is unable to forward authentication data, then the broker will only have the proxy's authentication data and the
originalPrincipal
.
Right.
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 thought the same thing, but the Proxy's role usually is a superuser, if we don't check the client's role, this is overstepping its authority, and the client can get the lookup data and topic data.
If we don't consider this case, I agree with you.
Can you describe the attack vector? From my perspective, I don't see how a client would be able to assume the proxy's role.
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.
When the proxy is forwarding authentication data, it seems sufficient to verify that the proxy's authentication data is valid for a proxy as a one time check during connection initialization. All subsequent auth challenges will go to the client anyway.
This is ProxyConnectionToBroker
operation, we also consider ProxyLookupRequests
logic.
Can you describe the attack vector? From my perspective, I don't see how a client would be able to assume the proxy's role.
Would you like to pass only the proxy's authentication data? If yes, that's going to cross the line.
In proxy, the connection logic between ProxyLookupRequests
and ProxyConnectionToBroker
is different.
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.
When the proxy is forwarding authentication data, it seems sufficient to verify that the proxy's authentication data is valid for a proxy as a one time check during connection initialization. All subsequent auth challenges will go to the client anyway.
This is
ProxyConnectionToBroker
operation, we also considerProxyLookupRequests
logic.
After #17831, when a proxy connection is in state ProxyLookupRequests
with forwardAuthorizationCredentials=true
, the proxy connection responds to the AuthChallenge
with the original client's auth data by forwarding the broker's challenge to the client. That is why I said the auth challenges go to the client in that case.
Would you like to pass only the proxy's authentication data? If yes, that's going to cross the line.
No, that's not my suggestion. I am suggesting that when the proxy sends both its authData
and the client's authData
, the broker needs to only verify the proxy's authData
at the beginning and at no other time because in all of those cases, the broker's auth challenge is going back to the original client and the proxy's authData
is never again updated. This is the case because the proxy only forwards the client's auth data when forwardAuthorizationCredentials=true
. One issue with my proposed solution is that the solution introduced in #17831 is not present in older versions of the proxy, so we'd need a way to address those proxies.
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.
Good explanation!
originalAuthState = | ||
originalAuthenticationProvider.newAuthState(clientData, remoteAddress, sslSession); | ||
} else { | ||
authState = authenticationProvider.newAuthState(clientData, remoteAddress, sslSession); |
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.
This does not feel right based on the AuthenticationState
interface, which provides hooks for calls to authenticate
. Can you provide additional motivation for this change?
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.
When authentication data changes, we need to renew the authentication state, and then we always get the correct data from that.
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 think the underlying problem is that calling authenticate
does not update the AuthenticationDataSource
in our token authentication provider. One solution is to recreate an auth state object. However, this has not been the implicit contract in the ServerCnx
for as long as we've had the AuthenticationState
. The contract has been that the AuthenticationState
lasts the whole life of the connection. I think we should update the TokenAuthenticationState
so that authenticate
updates the AuthenticationDataSource
.
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.
Right. We can fix built-in plugins easily, but we also need to consider third-party plugins.
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 actually don't think third-party plugins are going to be a problem here. The AuthenticationState
object has lived the whole life of the ServerCnx
already, so updating the TokenAuthenticationState#authenticate
implementation shouldn't be a problem. Or, when you say "third-party plugins", are you referencing to those plugins relying on the TokenAuthenticationState
? Even so, I think it's a pretty easy change, and I'd even consider it a bug since the AuthenticationDataSource
is static even though we try to update it in the ServerCnx
.
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 created #19282 to start a concrete discussion.
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.
Third-party plugins are the custom plug-in from users. I worry that breaks the user's plugin here if we don't recreate AuthenticationState
.
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 worry that breaks the user's plugin here if we don't recreate
AuthenticationState
.
We don't recreate the auth state now. Is there a specific case that you're worried about breaking?
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.
We don't recreate the auth state now. Is there a specific case that you're worried about breaking?
Sure.
This PR is a little big, so maybe I should split this PR. |
Sounds good to me. As far as making things asynchronous, I am happy to follow up on that work. I already have this draft for the |
Closed by #19519. |
Motivation
There is a bug that cannot update the authentication data variable during the auth challenge. The broker has two authentication data of proxy and user, the broker just updates the
authenticationData
during the auth challenge,originalAuthData
has been ignored, which causes the following problems:pulsar/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java
Line 705 in 72e0445
This should affect the 2.9, 2.10, and 2.11 versions.
NOTE: When the proxy forwards the authentication data of the user's client to the broker, the broker can only refresh the user's authentication data, and ignore the proxy's authentication data.
pulsar/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java
Line 805 in 631cd02
Modifications
org.apache.pulsar.broker.service.ServerCnx#doAuthentication
Verifying this change
The Pulsar test covers this change.
Documentation
doc
doc-required
doc-not-needed
doc-complete
Matching PR in forked repository
PR in forked repository: nodece#8