-
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
Add pluggable authorization mechanism #1200
Conversation
public interface AuthorizationProvider extends Closeable { | ||
|
||
/** | ||
* Provide a unique authorization name that can be passed by a client to get authorized. |
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 specify a bit more, with examples, on this?
* @param role | ||
* the app id used to send messages to the destination. | ||
*/ | ||
public CompletableFuture<Boolean> canProduceAsync(DestinationName destination, String 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.
I think we should maybe have some more informations available to the Authz implementation, such as the client credentials, which may be used in addition to "role" 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.
yes, that's correct, we should try to give as many info as possible as we may not have liberty to change interface later on. I will fix it.
*/ | ||
public CompletableFuture<Boolean> canLookupAsync(DestinationName destination, String 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.
Should we also use this interface to grant the permissions?
Eg: I might use a custom backend for authorization, but the same grant-permission could still work by writing through this interface.
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.
yes, that makes sense. I will add it.
if (provider != null) { | ||
return provider.canProduceAsync(destination, role); | ||
} | ||
CompletableFuture<Boolean> result = new CompletableFuture<>(); |
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 a FutureUtil.failedFuture(...)
utility
conf/proxy.conf
Outdated
@@ -49,6 +49,9 @@ authenticationProviders= | |||
# Enforce authorization | |||
authorizationEnabled=false | |||
|
|||
# Authorization provider name list, which is comma separated list of class names | |||
authorizationProviders=org.apache.pulsar.broker.authorization.PulsarAuthorizationProvider |
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.
What is the behavior when multiple backends are configured? at-least-once has to say "yes"? It might get tricky to define well, when there are multiple source of truth that we're following.
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.
if authMethod is not provided by client then AuthorizationService iterates over all the providers and look for one "yes".
However, right now, if client doesn't provide authMethodName then it I have kept default authMethod in protoAPI which makes broker to do authorization against default-existing-provider to avoid iteration over all available providers as all old client don't send authMethod.
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 it might not be always desirable to have the client choose which authorization backend to use. Do you have a concrete use case example to have multiple auth backends? I would actually just vote to have a single backend impl allowed. :)
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 don't have a strong opinion for having multiple providers but it can be useful when one wants to manage multiple authorization-systems for time being when they are migrating from one authorization provider to another. I agree that it's not desirable that client chooses the auth-method. I will remove support of multiple providers.
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.
Ok, it is always easier to add it if needed, then remove it later
import com.google.common.collect.Lists; | ||
import com.google.common.collect.Sets; | ||
|
||
import jersey.repackaged.com.google.common.collect.Maps; |
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.
Guava Maps
577d307
to
0a97ee9
Compare
@merlimat addressed all the comments |
285c544
to
168e5c5
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.
👍
fix: move FutureUtils to common and fix import add grantpermission api take default auth method pass authData to authorization provider keep single authorization provider
) ### Motivation The `AuthenticationDataSource` variable was added to the `ProxyConnection` class in #1200. It is no longer needed. Note that we store this variable in the `ServerCnx` because it is used for authorization. Because we do not do authorization in the proxy, we don't need it. ### Modifications * Remove unused variable ### Verifying this change This is a trivial change. ### Does this pull request potentially affect one of the following parts: The only conceivable way this is a breaking change is if a third party implementation implemented their library so that `authState.getAuthDataSource()` has a side effect. ### Documentation - [x] `doc-not-needed` <!-- Your PR changes do not impact docs --> No docs needed.
…che#19278) ### Motivation The `AuthenticationDataSource` variable was added to the `ProxyConnection` class in apache#1200. It is no longer needed. Note that we store this variable in the `ServerCnx` because it is used for authorization. Because we do not do authorization in the proxy, we don't need it. ### Modifications * Remove unused variable ### Verifying this change This is a trivial change. ### Does this pull request potentially affect one of the following parts: The only conceivable way this is a breaking change is if a third party implementation implemented their library so that `authState.getAuthDataSource()` has a side effect. ### Documentation - [x] `doc-not-needed` <!-- Your PR changes do not impact docs --> No docs needed. (cherry picked from commit a9b6519)
Motivation
As discussed in #1072, some times, we require to add pluggable authorization in broker, proxy, websocket.
Modifications
Add pluggable authorization mechanism. also made existing authorization as default provider.
Result
User can plugin custom authorization framework. It will not impact existing authorization's functionality and performance.
I will add documentation in separate PR once, we merge this change.