Fork me on GitHub

Programming, Internet & more

Roles & Permissions with Spring-Security 3

The Spring-Security approach to model roles and permissions is, in my opinion, very strange. In fact, out of the box you have either an overly simple approach with just users and roles, or a very complex heavy weigh approach with security on every domain object instance.

The most common requirement for security that I come across is that you want to have 3 types:

  • Users – which represents a user who can logon into a system
  • Roles – which consists of several users and several permissions
  • Permissions – which defines fine-granular access rights in the system

With these 3 types you can handle the most of the security challenges and at the same time it’s not an overly-complicated model.

In this tutorial I want to show you how to apply this approach to spring-security.


  • You should be familiar with spring in general and spring dependeny injection


You have to create 5 tables in a database of your choice to implement the described security model. In the following I will provide scripts to generate the tables in MySQL, but you can adjust the scripts to fit your database. You need the following tables:

  • users
  • roles
  • permissions
  • role_members
  • role_permissions

And here are the sql scripts to create these tables:

create table users(
  id bigint AUTO_INCREMENT not null primary key,
  username varchar(100) not null,
  password varchar(100) not null,
  enabled boolean not null);
create table roles(
  id bigint AUTO_INCREMENT not null primary key,
  name varchar(100) not null);
create table permissions(
  id bigint AUTO_INCREMENT not null primary key,
  name varchar(100) not null);
create table role_members(
  roles_id bigint not null,
  members_id bigint not null);

create table role_permissions(
  roles_id bigint not null,
  permissions_id bigint not null);

Spring Configuration

To tell spring that it should use the new security model, you have to implement a custom authentication-provider. To do this, you need to extend the spring class JdbcDaoImpl. At the moment it is sufficient to just implement an empty class here:


public class SpringSecurityDaoImpl extends JdbcDaoImpl {


Now in the spring configuration you can add the custom authentication provider and the newly created SpringSecurityDaoImpl. The authentication provider has a property groupAuthoritiesByUsernameQuery. You can use this property to provide an sql that retrieves the permissions of a user from the database.

 <authentication-provider user-service-ref="jdbcUserService">

<bean id="jdbcUserService"
  <property name="dataSource" ref="dataSource"/>
  <property name="enableGroups" value="true" />
  <property name="enableAuthorities" value="false" />
  <property name="groupAuthoritiesByUsernameQuery">
    <value>SELECT R.ID, R.NAME, P.NAME
            FROM ROLES R
            JOIN ROLE_MEMBERS RM on = RM.roles_id
            JOIN USERS U on = RM.members_id
            JOIN ROLE_PERMISSIONS RP ON RP.roles_id =
            JOIN PERMISSIONS P ON = RP.permissions_id
            WHERE U.username=?

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
  <property name="driverClassName" value="${db.driver}" />
  <property name="url" value="${db.url}" />
  <property name="username" value="${db.username}" />
  <property name="password" value="${db.password}" />

Using the security model

Now it is possible with spring to check if a user has a certain permission. Therefore you can use the common annotations provided by spring e.g. @PreAuthorize. Let’s say you want to check if a user has the permission to list products, you would have a permission readProducts in the permission table. You can now check if the user has the permission in your java code with:

public List getProducts() { ... }

Or you can do the check for permissions directly in the spring security config file:

<http use-expressions="true">        
  <intercept-url pattern="/productList.jsf" access="hasRole('readProducts')" />

The only drawback is that the name of the check method has the wrong name, it should be hasPermission() instead of hasRole(). But with this approach you can easily check for permissions.


You can find a full working example at GitHub.

Category: spring

1 Comment

  • marc says:

    Very interesting.

    I search something similar to that but a little different.

    I would like to add the project notion.

    An user could have different role for every project.

    For project X, a user could have admin_role, dev_role and for project y only user_role.

    Also permission could be different for role in function of project.

    Any idea how to modeling that?

Leave a Reply

Your email address will not be published. Required fields are marked *