The problem: hardcoded role-based authorization
One of the challenges around using Spring Security is that the examples—both in the documentation and on the web—tend to promote an overly-simple approach to role-based authorization, hardcoding roles in the source in a non-configurable fashion. For example:
@PreAuthorize("hasRole('facultyMember')")
public Newsletter getFacultyNews() { ... }
(Assume for the sake of example that ACL-based authorization is overkill for the method in question. The user either has permission to read faculty newsletters or not.)
The problem is that when we decide to make a change—for example, maybe teaching assistants should be allowed to read the faculty newsletters too—we have to go into the code to make a change:
@PreAuthorize("hasRole('facultyMember') or hasRole('teachingAssistant')")
public Newsletter getFacultyNews() { ... }
For domain object security there’s no problem because the permissions are cleanly separated from roles. We can map associate individual permissions on domain objects with users and roles as we wish. So the code contains annotations like
@PreAuthorize("hasPermission(#message, write)")
public void editMessage(Message message) { ... }
and all is good. We probably won’t need to change the relationship between the permission and the method itself; we’ll only need to change who (which users/roles) actually has the write permission on the message in question, and we can do that in the database. So that is nice, and we want the same thing for role-based authorization.
Solution: use granted authorities to model permissions, not roles
Here we assume an authentication source that models the desired relationship between users, roles and permissions. The typical relationship would be a many-many relationship between users and roles, and a many-many relationship between roles and permissions. For example:

It would be possible to have a direct relationship between users and permissions too (say to allow for the assignment of fine-grained permissions to specific users in addition to assigning roles), if that were desired.
The schema can be part of some standard authentication source or it can be a custom UserDetailsService; it doesn’t matter.
At the end of the day we need to transform our user representation into a UserDetails, and the trick is to map permissions—not roles—to GrantedAuthority objects to support the getAuthorities() contract on the UserDetails interface. We still have roles, but they matter only insofar as they help to bundle permissions up into convenient packages. The UserDetails implementation will probably expose the roles, but the UserDetails interface simply exposes the permissions (not the roles) via the getAuthorities() method.
It’s really that simple, and the final result is that we can avoid hardcoding roles in the code:
@PreAuthorize("hasRole('PERM_READ_FACULTY_NEWS')")
public Newsletter getFacultyNews() { ... }
As an aside, the predicate name hasRole rather than hasAuthority is a minor annoyance since permissions aren’t roles. The backing check is against a GrantedAuthority and so hasRole() seems to reflect either the intended or the typical use of GrantedAuthority.

By HERLoct_HENT December 7, 2010 - 10:30 am
This tip is save my tons of time. Thanks a lot.
By Ryan January 14, 2011 - 10:37 am
Great tip – this goes in line with the best practice I heard described by a spring security guy in an online video somewhere once.
(I also find it odd how they say hasRole instead of hasAuthority since it’s grantedAuthorities it is checking against)
By Iogui January 24, 2011 - 10:26 pm
It seems realy good but, how should I implement this solution?
Can you provide a more specific example?
Once a time, I’ve made something that seems similar to what you said.. (I’m not so shure, couse your tip is too abstract to me).. I just created tables to match user, role and permissions and configured a jdbc-user-service through the users-by-username-query and authorities-by-username-query atributes by using joins with all the tables.
In this way, when the spring used the query to get the authorization, I was giving the permissions obtained through the joins.
For example, I inserted one permission on the table with the name ‘ROLE_EDIT_DOCUMENT’ and used this like if it was a permission just to avoid spring hanging on me about the name diferent from ‘ROLE_**’.
But it seems ugly to make things work this way. This solution looks quite simple but I’m looking for a bether one.
.. then can you give some example so I can understand better?.. or you’re talking just about this same trick I made?
By Teerapong June 27, 2011 - 10:17 pm
I’m not sure but I think that is to override the method in User class
For me in Groovy, replace
Set getAuthorities() {
UserRole.findAllByUser(this).collect { it.role } as Set
}
with
Set getAuthorities() {
Set list = UserRole.findAllByUser(this).collect { it.role } as Set
def roles = new HashSet()
roles.addAll(list)
list.each {
//psudo code
add all permission relate to each role to ‘roles’ as Role object
}
}
If I’m wrong, please anyone help
By Markus February 4, 2011 - 6:34 am
Great posting! Thanks a lot.
The hasRole() instead of hasAuthority() shows that Spring Security isn’t as mature as other parts of the system.
Wouldn’t be surprised to see a hasAuthority() method (as a synonym with hasRole()) in the future.
By caravone February 16, 2011 - 4:53 pm
Thanks for the great tip — Regarding the “hasRole(…)” predicate in the @PreAuthorize annotation, you should be able to replace it with “hasAuthority(…)” with identical functionality (see http://static.springsource.org/spring-security/site/docs/3.0.x/apidocs/index.html).
In fact, “hasAuthority(…)” is just an alias for “hasRole(…)” (see https://fisheye.springsource.org/browse/spring-security/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionRoot.java?r=1c8d28501c6e7bf68f6a8f1c3027e88b256a7acb).
I have verified that this works at least with Spring Security 3.0.5.
By caravone February 16, 2011 - 4:55 pm
Oops, the first link should be http://static.springsource.org/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/access/expression/SecurityExpressionRoot.html
By gearond July 23, 2011 - 7:48 am
tHERE IS A SECURITY MODEL USED IN PHYSICAL SECURITY THAT SEEMS MORE AND MORE APPROPRIATE IN WEB BASED APPS. Hmmm, sorry for previous caps, cap key was on. Actions and web links have permissions, i.e., I can get into the building, to a certain floor, certain days of the week. But If I want access to the a safe deposit box, I need another layer of security.
This would be equivalent to normal framework (Spring, Symfony, Ruby on Rails, CakePHP) letting a user in the door via web pages, but having the Database or the ORM allow per record permissions, the safe deposit box is the last layer of security.
So if the gate guard is in the bathroom (some code screwed up the web interface), the safedeposit boxes (per record permissions) keeps the bad guy from getting easity into the family jewels
By Ketan Prajapati September 21, 2011 - 5:43 am
Hi,
It seems really cool solution.
But can u please tell me how to model permission instead of roles in Granted Authorities.
Can you please provide some code lines?
If you can share some sample application using above features then it will be better than best.
By devmsaleh October 27, 2011 - 1:42 am
can you please post the security xml configuration file ?
By ByteShuffler November 17, 2011 - 3:20 pm
Is there a way to achieve this using ldap authorization?
By Shameem December 9, 2011 - 2:28 pm
Hi,
There post is very interesting and I have question to Spring security. I need to implement a Cookie Based stateless authentication with Spring Security so that to make my application scalable.
Does anyone have any idea how to proceed.
Many thanks.
Shameem
By chemilleX3 April 18, 2012 - 11:31 pm
A very useful post!
Can you please post a sample implementation? I wanted to implement this on my current project. But I don’t have the idea on how to implement this. Can you please post a tutorial on how to achieve it? A sample app will do.
Please consider. Thanks.
By redfox26 July 7, 2012 - 3:20 pm
imagine if for every project we would like to manage role indepently.
we will need to add a table project and the table user_role coud be rename user_role_project ?
By Tu Pham August 17, 2012 - 11:43 am
Nice post, but you should redefine taglib to make function signature as we wish ( hasPermission ) for example
By Ruben November 5, 2012 - 8:53 am
Hello, thanks for this post. Quite helpful indeed, especially combined with your further clarification at stackoverflow: http://stackoverflow.com/questions/6357579/spring-security-with-roles-and-permissions
I have followed you approach and now when I log into my application and I retrieve the Authorization object like this..
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
The auth object contains the authorizations field which contains list of permissions (wrapped in GrantedAuthoriy objects) like PERM_ACCESS_ADMIN_SCREENS, PERM_FRY_CHICKENS, etc. But now I want to protect URLs like so:
but Spring complains: “Unsupported configuration attributes: [PERM_FRY_CHICKENS]”
Spring requires something that starts with ROLE_ in the ‘access’ attribute. But how then can I use my permissions to secure URLs?
Thanks in advance.
By Ruben November 5, 2012 - 8:57 am
Heck, I posted an excerpt from my Spring config, but it is removed by this blogging system
I am posting it again here with different brackets
{intercept-url pattern=”/manage*” access=”PERM_USER”/}