-
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
[feat][broker] Update AuthenticationProvider to simplify HTTP Authn #19197
[feat][broker] Update AuthenticationProvider to simplify HTTP Authn #19197
Conversation
@@ -160,6 +163,20 @@ public String authenticate(AuthenticationDataSource authData) throws Authenticat | |||
} | |||
} | |||
|
|||
@Override | |||
public boolean authenticateHttpRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { |
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.
Don't need to override authenticateHttpRequest
method.
See newHttpAuthState
method, we have wrapped the request
.
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 deprecates newHttpAuthState
because that method creates an object that is unnecessary and that triggers an authentication check for no reason in the OneStageAuthenticationState
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.
Note that I am leaving newHttpAuthState
as is in case someone already relies on the method itself.
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.
Your PR is awesome! but I have second thoughts about whether to deprecate the newHttpAuthState
, I don't suggest you deprecate this method,
- Using
newHttpAuthState
returnsAuthenticationState
, which includes role and authentication data, we can simply get these fromAuthenticationState
, and also quickly check the user authentication data. - Keep the same logic with the
newAuthState
, it looks cleaner.
This PR deprecates
newHttpAuthState
because that method creates an object that is unnecessary and that triggers an authentication check for no reason in theOneStageAuthenticationState
class.
I can accept authentication checks in the constructor of OneStageAuthenticationState
, it is a quick check.
Maybe we can improve here, but the Pulsar must explicitly call the authenticate
of 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.
My primary motivation for this PR is to implement PIP 97. If we want authentication to be asynchronous, we cannot assume that when the AuthenticationState
object is initialized, the authenticationDataSource
and the authRole
are present because the authentication might not yet be completed. My goal with this PR is to break an unnecessary relationship between AuthenticationState
and http request authentication that was created by #14044.
- Using
newHttpAuthState
returnsAuthenticationState
, which includes role and authentication data, we can simply get these fromAuthenticationState
, and also quickly check the user authentication data.
This is not the intention of the newHttpAuthState
method. The method was added by #14044 so that the AuthenticationDataSource
for an AuthenticationProvider
can be added on the http request as the AuthenticatedDataAttributeName
attribute on the request
. This PR proposes an alternate way to meet those criteria so that we can implement PIP 97.
- Keep the same logic with the
newAuthState
, it looks cleaner.
I disagree that it looks cleaner. The primary reason that we need a state object in the pulsar
protocol handlers is that we track isExpired
and whether or not the authentication is complete (first with isComplete
and in 2.12 with the result of the authenticationAsync
). We do not track state for individual HTTP request connections, so we shouldn't have a method to create a state object for HTTP requests.
Further, we're only building the AuthenticationState
object to get the AuthenticationDataSource
and we're not calling the AuthenticationState#authenticate
method. There is no need for this indirection. We can give AuthenticationProvider
implementations freedom to add the right request
attributes by using the authenticateHttpRequest
(and eventually authenticateHttpRequestAsync
).
Also, another problem is with the AuthenticationDataSource
in the AuthenticationState
. I think we should recreate the AuthenticationDataSource
each time we call authenticate
. However, if we have newHttpAuthState
, the AuthenticationState
object is not able to create a new AuthenticationDataSource
. I think the newHttpAuthState
creates an confusion about how to use the AuthenticationState
. This is a separate issue that I will follow up on in another PR.
I can accept authentication checks in the constructor of
OneStageAuthenticationState
, it is a quick check.
It does not matter that it is "quick". It is a waste of resources to verify authentication information twice.
Maybe we can improve here, but the Pulsar must explicitly call the
authenticate
ofAuthenticationState
.
This is already the way that Pulsar operates, but it has not been a stated requirement. I think this is essential for making authentication asynchronous. I will follow up with a separate 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.
Thank you for your explanation. This looks good to me.
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.
Thank you for sharing your concerns. It is great to have this context written down in the PR for future reference.
pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/AuthenticationFilter.java
Show resolved
Hide resolved
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.
LGTM
Codecov Report
@@ Coverage Diff @@
## master #19197 +/- ##
============================================
+ Coverage 47.04% 47.22% +0.18%
- Complexity 9190 18840 +9650
============================================
Files 607 1625 +1018
Lines 57677 132324 +74647
Branches 6007 14567 +8560
============================================
+ Hits 27132 62491 +35359
- Misses 27598 63528 +35930
- Partials 2947 6305 +3358
Flags with carried forward coverage won't be shown. Click here to find out more.
|
…pache#19197) PIP: apache#12105 This is the first of several PRs to implement [PIP 97](apache#12105). This PR seeks to start to solve the fact that the `AuthenticationState` class currently authenticates `authData` twice instead of just once. This change is important to make before we are able to utilize the async methods introduced in apache#12104. Historical context: apache#14044 introduced the `AuthenticationProvider#newHttpAuthState` method. The only use case for this method in the pulsar code base is to let custom providers specify the `AuthenticationDataSource` on http request attributes. The primary problem with that implementation is that the `AuthenticationState` class currently involves authenticating the `authData` passed in to the `newHttpAuthState`. As such, this code is sub-optimal, and creates a confusing flow. I propose we deprecate the `newHttpAuthState` method and instead start using the `authenticateHttpRequestAsync` and `authenticateHttpRequest` methods to allow custom implementations to configure the desired `AuthenticationDataSource` on the request attributes. In order to simplify the diff for reviewers, this PR uses the deprecated `AuthenticationProvider#authenticateHttpRequest` method. I plan to follow up and switch to use the `AuthenticationProvider#authenticateHttpRequestAsync` method. Note that these changes are completely backwards compatible. The only risk is to users that have custom code loaded into the broker that calls the `AuthenticationProvider#authenticateHttpRequest` method. * Deprecate `AuthenticationService#authenticateHttpRequest(HttpServletRequest request, AuthenticationDataSource authData)`. It is no longer used. * Deprecate `AuthenticationProvider#newHttpAuthState(HttpServletRequest request)`. It is no longer used outside of the `AuthenticationProvider` interface itself. * Remove `@InterfaceStability.Unstable` annotation from the `authenticateHttpRequestAsync` method. When I introduced that annotation, I was under the impression that we didn't need it. However, in order to meet the requirements introduced in apache#14044, we need to let custom `AuthenticationProviders` add their own attributes. * Update the default implementation of `authenticateHttpRequest`. Because the previous implementation was unreachable by all auth providers except for the SASL implementation, this is a backwards compatible change. * Implement changes for the `AuthenticationProviderToken` so that it no longer relies on `newHttpAuthState`. I added new tests. - [x] The public API This changes the public API within the broker by marking some methods as `@Deprecated`. - [x] `doc-not-needed` We document the `AuthenticationProvider` interface in the code. I added these docs. There is currently no where else to update docs. PR in forked repository: #12 My primary motivation for this PR is to implement PIP 97. If we want authentication to be asynchronous, we cannot assume that when the `AuthenticationState` object is initialized, the `authenticationDataSource` and the `authRole` are present because the authentication might not yet be completed. My goal with this PR is to break an unnecessary relationship between `AuthenticationState` and http request authentication that was created by apache#14044. (cherry picked from commit 3c38ed5)
PIP: #12105
Motivation
This is the first of several PRs to implement PIP 97.
This PR seeks to start to solve the fact that the
AuthenticationState
class currently authenticatesauthData
twice instead of just once. This change is important to make before we are able to utilize the async methods introduced in #12104.Historical context: #14044 introduced the
AuthenticationProvider#newHttpAuthState
method. The only use case for this method in the pulsar code base is to let custom providers specify theAuthenticationDataSource
on http request attributes. The primary problem with that implementation is that theAuthenticationState
class currently involves authenticating theauthData
passed in to thenewHttpAuthState
. As such, this code is sub-optimal, and creates a confusing flow.I propose we deprecate the
newHttpAuthState
method and instead start using theauthenticateHttpRequestAsync
andauthenticateHttpRequest
methods to allow custom implementations to configure the desiredAuthenticationDataSource
on the request attributes.In order to simplify the diff for reviewers, this PR uses the deprecated
AuthenticationProvider#authenticateHttpRequest
method. I plan to follow up and switch to use theAuthenticationProvider#authenticateHttpRequestAsync
method.Note that these changes are completely backwards compatible. The only risk is to users that have custom code loaded into the broker that calls the
AuthenticationProvider#authenticateHttpRequest
method.Modifications
AuthenticationService#authenticateHttpRequest(HttpServletRequest request, AuthenticationDataSource authData)
. It is no longer used.AuthenticationProvider#newHttpAuthState(HttpServletRequest request)
. It is no longer used outside of theAuthenticationProvider
interface itself.@InterfaceStability.Unstable
annotation from theauthenticateHttpRequestAsync
method. When I introduced that annotation, I was under the impression that we didn't need it. However, in order to meet the requirements introduced in [broker][authentication]Support pass http auth status #14044, we need to let customAuthenticationProviders
add their own attributes.authenticateHttpRequest
. Because the previous implementation was unreachable by all auth providers except for the SASL implementation, this is a backwards compatible change.AuthenticationProviderToken
so that it no longer relies onnewHttpAuthState
.Verifying this change
I added new tests.
Does this pull request potentially affect one of the following parts:
This changes the public API within the broker by marking some methods as
@Deprecated
.Documentation
doc-not-needed
We document the
AuthenticationProvider
interface in the code. I added these docs. There is currently no where else to update docs.Matching PR in forked repository
PR in forked repository: michaeljmarshall#12