2

I want to implement permission-based access control as discussed in this post.

I am not familiar with the implementation - is there any detailed example on how to implement this from start to finish?

Rob Hruska
  • 118,520
  • 32
  • 167
  • 192
chemilleX3
  • 1,176
  • 5
  • 17
  • 27

2 Answers2

0

Have you seen the Spring security plugin? Main docs are here

As in this post you could also consider the Shiro plugin as well. I find the Spring security plugin a simpler but the Shiro one does have some advantages as discussed in the post.

Community
  • 1
  • 1
Steve
  • 1,457
  • 12
  • 25
  • 1
    Thank you so much for the post! Actually, I am currently using spring security core plugin. What I wanted to do is to implement permission-based, instead of role-based access control. But so far, I cant find a way on how to completely implement it. – chemilleX3 Apr 24 '12 at 04:10
  • 1
    Oh sorry I misread your question. An interesting posting, all I can guess is that you will need to extend the basic User/Role domain model and implement a custom UserDetailsService. Seems to complicate things but if you really need it the solution could be slick. – Steve Apr 24 '12 at 04:55
  • 1
    Thank you so much Steve! Can you post an example on how to use the UserDetailsService in connection to my concern? It would be a great help! Thanks! – chemilleX3 Apr 24 '12 at 05:37
  • 1
    Sorry I dont have an example but I think try following the customer UserDetailsService: http://grails-plugins.github.com/grails-spring-security-core/docs/manual/guide/11%20Custom%20UserDetailsService.html and extend the User/Role domain model given with the spring security plugin to include the domain classes in the link you provided. Now how to include these in the annotations or taglibs it owuld be great to write your own but u could do this with the existing rule based method, see: http://static.springsource.org/spring-security/site/docs/3.0.x/reference/el-access.html#el-common-built-in – Steve Apr 26 '12 at 01:19
0

I have just solved this (mostly) so I post it here for reference. This solution works on Grails 2.2.4 and Spring Security 2.0 RC

1) Security Domain Model You model your security domain classes as described in the article, so you will have these domains in the end: - Permission - Role - RolePermission - User - UserRole

2) Querying authorities for users You make sure that your User class returns Permissions instead of Roles as authorities in the getAuthorities() method:

  /**
   * Gets authorities for the user.
   * 
   * It will return all of the Permissions of the User assigned by the Roles
   * which the User has
   */
  Set<Permission> getAuthorities() {

    Set allPermissions = []
    // Collect all Roles of the User
    UserRole.findAllByUser(this).each { userRole ->
      // Collect all Permissions from the Role  
      Role role = userRole.role
      // Returning the collected permissions
      RolePermission.findAllByRole(role).each { rp ->
        allPermissions.add(rp.permission)
      }
    }
    return allPermissions
  }

3) Spring Security Config

I have this in my Config.groovy for Spring Security configuration (non-relevant parts omitted):

grails {
  plugin {
    springsecurity {
      ...      
      userLookup {
        userDomainClassName = 'limes.security.User'
      }
      authority {
        nameField = 'name'
        className = 'limes.security.Permission'
      }
      ...
    }
  }
}

One important highlight is the authority.nameField which MUST conform with your Permission class. The name attribute is called 'name' in my model (and the article).

Naturally, you set your Permission class as the authority.className in order to make it fit with the return values of User.getAuthorities().

4) Using in security expressions

The solution above does not solve the limitation of the Grails Spring Security plugin that you can use only authority name starting with "ROLE_".

So, if you want to call your permissions like "PERM_PERMISSION1", than you have to write EL expressions for checks everywhere (notybly on controller @Secured annotations and static url rules).

So instead of

@Secured(["PERM_PERMISSION1"])

You write

@Secured(["hasRole('PERM_PERMISSION1')"])
sola
  • 1,498
  • 14
  • 23