-
Notifications
You must be signed in to change notification settings - Fork 6k
hasAuthority and custom Mono<Boolean> method in @PreAuthorize leads to ConverterNotFoundException error #15209
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
@bskorka, thanks for the report. Will you please try the following? Change @PreAuthorize("@authz.checkEverything(#root)"`) Then, introduce the above bean in such a way that it checks all three conditions. Can you confirm that this allows you to return In the meantime, I will take a look and see what can be done about supporting expression elements that return a mixture of |
Hey @jzheaux! The implementation of this approach looks like this: public class TestController {
@GetMapping("/values")
@PreAuthorize("@userConnectionAuthorizerService.hasUserAccessToConnectionData(#id))")
public Mono<ApiResponse<List<TestObject>>> getAllValues(@RequestParam Integer id,
@RequestParam List<Status> statuses,
@RequestParam(required = false, defaultValue = "false") Boolean latest) {
return ...
}
} public class UserConnectionAuthorizerServiceImpl implements UserConnectionAuthorizerService {
private final PreAuthService preAuthService;
@Override
public Mono<Boolean> hasUserAccessToConnectionData(Long id) {
return Mono.zip(
preAuthService.hasAuthority(Permissions.PPCV_BROWSE.getValue()),
preAuthService.hasAuthority(Permissions.PPCV_BROWSE_SCOPED.getValue())
)
.flatMap(tuple -> tuple.getT1() ? Mono.just(true) :
tuple.getT2() ? checkUserConnection(id) : // business check, same as isUserConnected in previous example
Mono.just(false)
)
.switchIfEmpty(Mono.just(false));
}
} public class PreAuthServiceImpl implements PreAuthService {
public Mono<Boolean> hasAuthority(String authority) {
return ReactiveSecurityContextHolder.getContext()
.map(SecurityContext::getAuthentication)
.map(authentication -> authentication.getAuthorities().stream()
.anyMatch(grantedAuthority -> grantedAuthority.getAuthority().equals(authority)));
}
} I understand that handling the mix of |
Ideally we should be able to look at a method and see what are the authorities needed for executing this method. With this current approach, all the checks are hidden. It also looks like we can't define two reactive methods in the @PreAuthorize SpEl as well, which maybe would've helped with this a bit. |
Describe the bug
After upgrading to Spring Boot 3.3.0 and Spring Security 6.3.0 I've tried to migrate my single
Mono<Boolean>
@PreAuthorize
calls to more complex ones as I thought that these tasks make it possible:However, if we want to use the
@PreAuthorize
connected with aMono<Boolean>
andhasAuthority
we are getting an errorNo converter found capable of converting from type [reactor.core.publisher.MonoFlatMap<java.lang.Boolean, ?>] to type [java.lang.Boolean]
To Reproduce
@EnableReactiveMethodSecurity
configuration@PreAuthorize
usageMono<Boolean>
and call the endpoint - it works@PreAuthorize
- the exception will be thrown on callExpected behaviour
The "complex"
@PreAuthorize
expression should be handled without isues if we use methods returningMono<Boolean>
and built-inhasAuthority
calls.Sample
When running code in the integration tests I receive:
The text was updated successfully, but these errors were encountered: