We’re developing an app (using Grails Spring Security (formerly Acegi)) in which we’ll have thousands of users that span 10-15 discreet user types. In the current system, each user type equates to a “group”, and the specific roles and permissions are tied to the group. The user gets all their “roles” from the group.
For example, we might have two user groups:
CLOWN: roles = ride_clown_car, toot_horn, receive_applause
ACROBAT: roles = do_flip, walk_tightrope, receive_applause
We have three users, one assigned to the CLOWN group, one assigned to the ACROBAT group, and one assigned to both (has union of CLOWN and ACROBAT roles).
If we change permissions, we do so at the group level. For example, if we add a swing_on_trapeze permission to the ACROBAT group, all acrobats will automatically inherit it.
In Grails terms, the permissions on the controllers would still be at the role level. So an action with @Secured ([‘toot_horn’]) would allow users in the CLOWN group but not in the ACROBAT group. @Secured ([‘receive_applause’]) would allow both CLOWNS and ACROBATS.
How would I do this in Spring Security given the two-tiered nature of the model (user, role)? Do I need to implement my own custom authentication to collect roles based via groups?
Thanks!
You should be using the new Spring Security Core plugin since the Acegi plugin isn’t being developed and is basically deprecated.
But either way, both plugins just expect that there’s something like a
getAuthorities()method in your user class that returns role instances. In a scenario like this where the user has many groups, just collect all of the groups’ roles:This assumes that you have a many-to-many between User and Group:
and Group has a many-to-many with Role:
To use this set the ‘relationalAuthorities’ property to ‘allRoles’ in SecurityConfig.groovy so it uses that instead of the many-to-many between user and role:
There’s no configuration required for the Spring Security core plugin since it depends on an application-defined getAuthorities method already, so just use something like this in your User class: