Search code examples
grailsspring-securityuser-roles

Spring Security check if User has RoleGroup


I have the domain:

User hasOne RoleGroup hasMany Role

  • Exemples:

RoleGroup: Admin, Professional, Client, ...

Role: ROLE_ACTION_1, ROLE_ACTION_2, ...

How I check if a user has a RoleGroup with annotation @Secured?

I need to check if user contains all roles of RoleGroup?

User class:

class User implements Serializable {

    private static final long serialVersionUID = 1

    static constraints = {
        password blank: false, password: true
        username blank: false, unique: true
    }

    static mapping = {
        password column: '`password`'
        version false
        table schema: "CA"
    }

    static transients = ['springSecurityService']

    transient springSecurityService

    transient boolean enabled = true
    transient boolean accountExpired
    transient boolean accountLocked
    transient boolean passwordExpired

    String username
    String password
    RoleGroup profile

    Set<RoleGroup> getAuthorities() {
        [profile]
    }
}

RoleGroup class:

class RoleGroup implements Serializable {

    private static final long serialVersionUID = 1

    String name    

    Set<Role> getAuthorities() {
        RoleGroupRole.findAllByRoleGroup (this)*.role
    }    
}

Solution

  • I think you have not fully grasped spring security.

    When using annotation - first annotation must be enabled in the config - this is the case by default.

    You then secure either an entire controller or a controller action using something like this

    @Secured(['ROLE_ADMIN', 'ROLE_USER'])
    

    It has no way of working out all of what the user has as authority groups.

    Although in the code you pasted in the RoleGroup class you have :

    getAuthorities()
    

    I have tweaked my User domain class and added the following:

       Set<RoleGroup> getAuthorities() {
            UserRoleGroup.findAllByUser(this)*.roleGroup
        }
        Set<RoleGroup> getAuthoritiesNames() {
            UserRoleGroup.findAllByUser(this)*.roleGroup?.name
        }
    

    So when I have a user

    i.e. User user=User.get(1L)

    def authorities = user.getAuthorities()
    println "user ${user} has ${authorities}"
    

    which is a list containing all the authorities

    if (authorities.contains('ROLE_USER'))  {
    println "WOOHOO"
    }
    

    With spring security you could also use it within gsps:

      <sec:ifAllGranted roles="ROLE_ADMIN">
    show something
    </sec:ifAllGranted>
    

    So back to your question:

    You have :

    Set<RoleGroup> getAuthorities() {
            [profile]
        }
    

    Is that something you have in put in place ?

    From where it is :

    class RoleGroup implements Serializable {
    
        private static final long serialVersionUID = 1
    
        String name    
    
        Set<Role> getAuthorities() {
            RoleGroupRole.findAllByRoleGroup (this)*.role
        }    
    }
    

    This should list you all the authorities

    User user = User.get(1L)
    def authorities = user?.profile?.getAuthorities()