Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security (Acegi) and user Groups (vs. Roles)

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!

like image 229
ecodan Avatar asked Jul 06 '10 20:07

ecodan


People also ask

What are roles in Spring Security?

The Role represents the high-level roles of the user in the system. Each role will have a set of low-level privileges. The Privilege represents a low-level, granular privilege/authority in the system.

Which class in Spring Security framework is used to define role?

The UserDetailsService is a core interface in Spring Security framework, which is used to retrieve the user's authentication and authorization information. This interface is also responsible to provide the User's GrantedAuthority list, which is used to derive our spring security roles and permissions for the user.


1 Answers

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:

class User {
   ...
   def getAllRoles() {
      Set allRoles = []
      groups.each { allRoles.addAll it.roles }
      allRoles
   }
}

This assumes that you have a many-to-many between User and Group:

static hasMany = [groups: Group]

and Group has a many-to-many with Role:

static hasMany = [roles: 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:

relationalAuthorities='allRoles'

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:

Set<Role> getAuthorities() {
   Set allRoles = []
   groups.each { allRoles.addAll it.roles }
   allRoles
}
like image 192
Burt Beckwith Avatar answered Oct 02 '22 04:10

Burt Beckwith