Reputation: 5071
My Java application uses Spring's @PreAuthorize("hasAuthority('SomeScopeName')")
on methods to assert that the user is authorized to perform the actions in the methods. This annotation throws an AccessDeniedException
if the user is unauthorized:
@Override
@PreAuthorize("hasAuthority('SomeScopeName')")
public void assertHasDisplayAuthorization() {
// empty on purpose
}
One of the application's endpoints wants to inform the user interface about which actions the user is able to perform. For that, it calculates an Authorizations
object that renders as JSON like { canDisplay: true, canEdit: false, ... }
:
public Authorizations getAuthorizations() {
return new Authorizations(hasDisplayAuthorization(), hasEditAuthorization(), ...);
}
That calculation calls the @PreAuthorize
'd methods to determine the user's authorization:
private boolean hasDisplayAuthorization() {
try {
validator.assertHasDisplayAuthorization();
return true;
} catch (AccessDeniedException e) {
return false;
}
}
This works, but I don't like the fact that I need to throw and catch an exception just to calculate a simple true/false.
Is there a possibility to calculate the Authorizations
object without having to throw exceptions?
For example, would it be possible and reliable to calculate the authorization in an @Value
annotation and just assign it to an object attribute?
@Value("hasAuthority('SomeScopeName')")
boolean canDisplay;
... return new Authorizations(canDisplay, ...);
Upvotes: 0
Views: 44
Reputation: 5145
Instead of using @PreAuthorize
, you can do it manually using the following class:
public class SecurityHelper {
public static boolean hasAuthority(String authority) {
Collection<? extends GrantedAuthority> authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
return authorities.contains(new SimpleGrantedAuthority(authority));
}
}
Then, you can define an additional class with methods for checking each scope, for example:
public class AuthorityChecker {
public static boolean hasDisplayAuthorization(){
return SecurityHelper.hasAuthority("SomeScopeName");
}
//...
}
Keep in mind, that it will work as long as SecurityContext
is available in the current thread, otherwise, it will throw an exception.
Upvotes: 1