Spring Security with roles and permissions
I'm the author of the article in question.
No doubt there are multiple ways to do it, but the way I typically do it is to implement a custom UserDetails
that knows about roles and permissions. Role
and Permission
are just custom classes that you write. (Nothing fancy--Role
has a name and a set of Permission
instances, and Permission
has a name.) Then the getAuthorities()
returns GrantedAuthority
objects that look like this:
PERM_CREATE_POST
, PERM_UPDATE_POST
, PERM_READ_POST
instead of returning things like
ROLE_USER
, ROLE_MODERATOR
The roles are still available if your UserDetails
implementation has a getRoles()
method. (I recommend having one.)
Ideally you assign roles to the user and the associated permissions are filled in automatically. This would involve having a custom UserDetailsService
that knows how to perform that mapping, and all it has to do is source the mapping from the database. (See the article for the schema.)
Then you can define your authorization rules in terms of permissions instead of roles.
Hope that helps.
The basic steps are:
Use a custom authentication provider
<bean id="myAuthenticationProvider" class="myProviderImplementation" scope="singleton"> ... </bean>
Make your custom provider return a custom
UserDetails
implementation. ThisUserDetailsImpl
will have agetAuthorities()
like this:public Collection<GrantedAuthority> getAuthorities() { List<GrantedAuthority> permissions = new ArrayList<GrantedAuthority>(); for (GrantedAuthority role: roles) { permissions.addAll(getPermissionsIncludedInRole(role)); } return permissions; }
Of course from here you could apply a lot of optimizations/customizations for your specific requirements.
To implement that, it seems that you have to:
- Create your model (user, role, permissions) and a way to retrieve permissions for a given user;
- Define your own
org.springframework.security.authentication.ProviderManager
and configure it (set its providers) to a customorg.springframework.security.authentication.AuthenticationProvider
. This last one should return on its authenticate method a Authentication, which should be setted with theorg.springframework.security.core.GrantedAuthority
, in your case, all the permissions for the given user.
The trick in that article is to have roles assigned to users, but, to set the permissions for those roles in the Authentication.authorities
object.
For that I advise you to read the API, and see if you can extend some basic ProviderManager and AuthenticationProvider instead of implementing everything. I've done that with org.springframework.security.ldap.authentication.LdapAuthenticationProvider
setting a custom LdapAuthoritiesPopulator, that would retrieve the correct roles for the user.
Hope this time I got what you are looking for. Good luck.