1. Overview

JHipster comes with two default roles – USER and ADMIN – but sometimes we need to add our own.

In this tutorial, we’ll create a new role named MANAGER that we can use to provide additional privileges to a user.

Note that JHipster uses the term authorities somewhat interchangeably with roles. Either way, we essentially mean the same thing.

2. Code Changes

The first step for creating a new role is to update the class AuthoritiesConstants. This file is automatically generated when we create a new JHipster application and contains constants for all the roles and authorities in the application.

To create our new MANAGER role, we simply add a new constant into this file:

public static final String MANAGER = "ROLE_MANAGER";

3. Schema Changes

The next step is to define the new role in our data store.

JHipster supports a variety of persistent data stores and creates an initial setup task that populates the data store with users and authorities.

To add a new role into the database setup, we must edit the InitialSetupMigration.java file. It already has a method called addAuthorities, and we simply add our new role into the existing code:

public void addAuthorities(MongoTemplate mongoTemplate) {
    // Add these lines after the existing, auto-generated code
    Authority managerAuthority = new Authority();
    managerAuthority.setName(AuthoritiesConstants.MANAGER);
    mongoTemplate.save(managerAuthority);
}

This example uses MongoDB, but the steps are very similar to the other persistent stores that JHipster supports.

Note that some data stores, such as H2, rely solely on a file named authorities.csv, and thus do not have any generated code that requires updating.

4. Using Our New Role

Now that we have a new role defined let’s look at how to use it in our code.

4.1. Java Code

On the backend, there are two primary ways to check if a user has the authority to perform an operation.

First, we can modify SecurityConfiguration if we want to limit access to a particular API:

public SecurityFilterChain filterChain(HttpSecurity http, MvcRequestMatcher.Builder mvc) throws Exception {
    http.authorizeHttpRequests(authz -> authz.requestMatchers(mvc.pattern("/management/**"))
        .hasAuthority(AuthoritiesConstants.MANAGER));
    return http.build();
}

Second, we can use SecurityUtils anywhere in our application to check if a user is in a role:

if (SecurityUtils.isCurrentUserInRole(AuthoritiesConstants.MANAGER)) {
    // perform some logic that is applicable to manager role
}

4.2. Front-End

JHipster provides two ways to check for roles on the front-end. Note that these examples use Angular, but similar constructs exist for React.

First, any element in a template can use the *jhiHasAnyAuthority directive. It accepts a single string or array of strings:

<div *jhiHasAnyAuthority="'ROLE_MANAGER'">
    <!-- manager related code here -->
</div>

Second, the Principal class can check if a user has a particular role:

isManager() {
    return this.principal.identity()
      .then(account => this.principal.hasAnyAuthority(['ROLE_MANAGER']));
}

5. Conclusion

In this article, we’ve seen how simple it is to create new roles and authorities in JHipster. While the default USER and ADMIN roles are a great starting point for most applications, additional roles provide more flexibility.

With additional roles, we have greater control over which users can access APIs and what data they can see in the front-end.

As always, the code is available over on GitHub.