Reputation: 1848
The JAVA EE @DeclareRoles
annotation is a way to declare the list of possible roles of the users to match with the annotation @RolesAllowed
.
But what if our roles are stored in database and if the list of the potential roles is long ?
I currently use roles to specify an atomic access to functionnalities on my website, so I have a long list of roles as some users can access functionnality-1 but not the 2, and some can on the 2 but not on the 1, etc...
I want to avoid editing the @DeclareRoles
annotation every time I am creating a new role for a new functionnality, so the question is :
Is there any way to programmatically setup the @DeclareRoles annotation or to specify that it should load from a database ?
Upvotes: 1
Views: 617
Reputation: 2321
Since the introduction of the JavaEE 8 security API you have the ability to write your own identity store. This allows you to fetch users and user data from a custom location and a custom service. You asked about using a database - so here is an example using a database facade together with a custom identity store;
@ApplicationScoped
public class MyIdentityStore implements IdentityStore {
@EJB private UserFacade userFacade;
@Override
public int priority() {
return 50;
}
@Override
public Set<ValidationType> validationTypes() {
return EnumSet.of(ValidationType.PROVIDE_GROUPS, ValidationType.VALIDATE);
}
@Override
public Set<String> getCallerGroups(CredentialValidationResult validationResult) {
final String userName = validationResult.getCallerPrincipal().getName();
final User user= usersFacade.find(userName);
return user.getRoles();
}
public CredentialValidationResult validate(UsernamePasswordCredential credential) {
/* Handle validation/login of the user here */
}
}
To explain the above slightly more - the getCallerGroups()
will return the roles that the user is part of - something you can then use throughout the JavaEE security API and lockdown methods such as @RolesAllowed
. The validate()
method handles the validation of the user when a check is requested by the container. Finally, the validationTypes()
method simply specifies what this Identity store should be used for - in this case we have specified both the fetching of roles and handling of validation.
So since EE8 introduced this - it has become really flexible and easy to take advantage of the security features in the platform.
Here are some really great references on the subject;
https://www.ibm.com/developerworks/library/j-javaee8-security-api-1
https://www.ibm.com/developerworks/library/j-javaee8-security-api-2
https://www.ibm.com/developerworks/library/j-javaee8-security-api-3
https://www.baeldung.com/java-ee-8-security
Upvotes: 1