robinvrd
robinvrd

Reputation: 1848

Define @DeclareRoles annotation programmatically

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

Answers (1)

Adam Waldenberg
Adam Waldenberg

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

Related Questions