3 min read

Spring Security (series) - Authorities and Roles #6


Now that we know who you are, let's see what you CAN do 🧐 !


So we got through with the Authentication flow where we identify the user and we saw that there are more than a few ways to do that (database, third-party) . We move into the Authorization part of Security.


Authorization is the process where we check the permissions of a user to do certain actions.

Spring Security provides us two main concepts by which we define permissions:

  • Authority - action-based permissions (ex: canReadTransactions, canDeleteUser)
  • Role - role-based permissions (ex: Admin, Client, BackOffice)

Practically, there is no conceptual difference between them. A role is only an authority prefixed with 'ROLE_'

public UserBuilder roles(String... roles) {
    List<GrantedAuthority> authorities = new ArrayList<>(roles.length);
    for (String role : roles) {
				() -> role + " cannot start with ROLE_ (it is automatically added)");
        authorities.add(new SimpleGrantedAuthority("ROLE_" + role));
    return authorities(authorities);

Continuing on the footsteps of the database login example, let's create two endpoints that we will secure by only letting some users access them:

  • /admin - can only be access by users with ADMIN role
  • /client - can only be access by users with CLIENT role
public class Controller {

    public String admin() {
        return "Admin";

    public String client() {
        return "Client";

And for the security configuration, we only need to override the configure(HttpSecurity http) of the WebSecurityConfigurerAdapter and use the mvcMatchers to match URLs with roles.

public class SecurityConfig extends WebSecurityConfigurerAdapter {


protected void configure(HttpSecurity http) throws Exception {

Actually defining the roles for some users will require us creating 2 new tables:

  • role - where we define the roles in our application
  • user_x_role - where we match roles with users.

We need to define the Role entity matching the role table.

@Table(name = "role", schema = "public")
public class Role {

    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @Column(name = "role")
    private String role;

And then, the roles need to be added to the User entity.

@Table(name = "user", schema = "public")
public class User {
    @ManyToMany(cascade = {
    }, fetch = FetchType.EAGER)
    @JoinTable(name = "user_x_role",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "role_id")
    private Set<Role> roles = new HashSet<>();

(I know that fetch = FetchType.EAGER is not the best thing to do in terms of performance, but for this example, it will do the trick)

The last link in the chain is to add the roles to the Spring Security UserDetails object that gets added in the Security Context on a successful authentication.

public class CustomUserDetails implements UserDetails {
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return user.getRoles().stream()
                .map(role -> new SimpleGrantedAuthority(role.getRole()))

Testing it with Postman:

As always, you can find the full code here: https://github.com/andreiszu/spring-security/tree/authorities-roles

Don't miss out on more posts like this! Susbcribe to our free newsletter!
Currently I am working on a Java Interview e-book designed to successfully get you through any Java technical interview you may take.
Stay tuned! 🚀