-
Notifications
You must be signed in to change notification settings - Fork 6k
Add SpEL Support for Reactive AuthorizeExchangeSpec #6512
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
Comments
Thanks for the feedback. I'm not sure it makes sense to allow SpEL here given that the baseline JDK version is Java 8 which allows for lambdas. Using a lambda is much simpler and will allow for better performance. Can you explain why you want SpEL vs using a lambda? PS: It should be noted that SpEL also doesn't work that well for reactive types. For example, expressing something like |
Hi @rwinch,
Or
and so on. This feature is enabled for not reactive, passing has_Authority("ROLE_1") && has_Authority("ROLE_2") as SpEl in access method. Can I have a similar possibility for the Reactive AuthorizeExchangeSpec? Or you can support me with an example (with lambda expression or not) that performs my Desiderable Behavior? |
.access("ROLE_1 || ROLE_2")For the first example, gh-6306 (5.2.0.M1) added support to use http
.authorizeExchange()
.anyExchange().hasAnyRole("1", "2"); Alternatively, you can do something like: import static org.springframework.security.authorization.AuthorityReactiveAuthorizationManager.hasRole;
ReactiveAuthorizationManager<AuthorizationContext> hasRole1OrRole2 = (authN, ctx) ->
Flux.just(hasRole("1"), hasRole("2"))
.flatMap(a -> a.check(authN, ctx))
.filter(AuthorizationDecision::isGranted)
.next();
http
.authorizeExchange()
.anyExchange().access(hasRole1OrRole2); .access("!ROLE_1")This is a sample using lambdas and building off the components that already exist. import static org.springframework.security.authorization.AuthorityReactiveAuthorizationManager.hasRole;
ReactiveAuthorizationManager<AuthorizationContext> notRole1 = (authN, ctx) ->
hasRole("ROLE_1").check(authN, ctx)
.map(r -> !r.isGranted())
.map(AuthorizationDecision::new);
http
.authorizeExchange()
.anyExchange().access(notRole1); If you want you can also look at the actual implementation of AuthorityReactiveAuthorizationManager to see how you could place this in your own class. Looking at that code gives you a better idea of exactly how you would do something even more advanced too. I'm closing this as we don't plan on providing SpEL support for the reasons mentioned above |
Thanks for the suggestion. I have implemented OR and AND expression in reactive. For the AND: ReactiveAuthorizationManager<AuthorizationContext> hasRole1AndRole2 = (authN, ctx) ->
Flux.just(hasRole("1"), hasRole("2"))
.flatMap(a -> a.check(authN, ctx))
.filter(a -> !a.isGranted()).hasElements()
.map(b -> b.booleanValue() ? new AuthorizationDecision(false) : new AuthorizationDecision(true));
http.authorizeExchange().anyExchange().access(hasRole1AndRole2); But for the OR your code is not correct because it will authorize also when there isn't at least an user granted. So I have corrected in this: ReactiveAuthorizationManager<AuthorizationContext> hasRole1OrRole2 = (authN, ctx) ->
Flux.just(hasRole("1"), hasRole("2"))
.flatMap(a -> a.check(authN, ctx))
.filter(a -> a.isGranted()).defaultIfEmpty(new AuthorizationDecision(false)).next();
http.authorizeExchange().anyExchange().access(hasRole1OrRole2); |
Summary
Non-reactive spring security (4.x) provides access method where you can pass an Expression-Based-Access-Control to evaluate and/or authority/role permissions for allowing access.
In the reactive spring security the access method require an implementation of ReactiveAuthorizationManager or you can use a static method of it:
In the spring-security 5.2.x development version you are supporting also the hasAnyAuthority and hasAnyRole methods, as spring-security 4.x, specified in #6306:
It would be great to have also the access method with String Expression-Based-Access-Control in the reactive API as well.
Actual Behavior
Where CustomReactiveAuthorizationManager is a my implementation of ReactiveAuthorizationManager interface similar to AuthorityReactiveAuthorizationManager.
But the last I can't use because the constructor is private.
So I can use only the static methods provided to evaluate OR boolean result from a list of roles/authorities:
or
Expected Behavior
Configuration
Not applicable.
Version
5.2.x
Sample
Not applicable.
The text was updated successfully, but these errors were encountered: