With Spring Security 5.5 you can use a custom AuthorizationManager
when using the AuthorizeHttpRequestsConfigurer
.
public class DelegatingMultiAuthorizationManager<T> implements AuthorizationManager<T> {
private final List<AuthorizationManager<T>> authorizationManagers;
public DelegatingMultiAuthorizationManager(List<AuthorizationManager<T>> authorizationManagers) {
this.authorizationManagers = authorizationManagers;
}
public static <T> DelegatingMultiAuthorizationManager<T> hasAll(AuthorizationManager<T>... authorizationManagers) {
Assert.notEmpty(authorizationManagers, "authorizationManagers cannot be empty");
Assert.noNullElements(authorizationManagers, "authorizationManagers cannot contain null values");
return new DelegatingMultiAuthorizationManager(Arrays.asList(authorizationManagers));
}
@Override
public AuthorizationDecision check(Supplier<Authentication> authentication, T object) {
for (AuthorizationManager<T> authorizationManager : authorizationManagers) {
AuthorizationDecision decision = authorizationManager.check(authentication, object);
if (decision == null || !decision.isGranted()) {
return new AuthorizationDecision(false);
}
}
return new AuthorizationDecision(true);
}
}
This AuthorizationManager requires each provided AuthorizationManager to grant access. If any of them does not grant access the authorization will fail.
You can then use it like this (which also allows using constants):
http.authorizeHttpRequests(authorize -> authorize
.antMatchers("/something/*")
.access(DelegatingMultiAuthorizationManager
.hasAll(AuthorityAuthorizationManager.hasAuthority("auth_a"),
AuthorityAuthorizationManager.hasAuthority("auth_b")))
hasAuthority() and hasAuthority() and hasAuthority()
for@Secured
andaccess()
when using theExpressionUrlAuthorizationConfigurer
. – Christoper@PreAuthorise
, not@Secured
? – Radar