Announcement Announcement Module
Collapse
No announcement yet.
Many-to-many relation for spring-security-core users/roles Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Many-to-many relation for spring-security-core users/roles

    I would like to be able to modify the roles assigned to a user from the user edit/create page.
    Is there a way to define the User domain class such that the generated views will allow the selection of Roles?

    Do I have to do something like this in User class:
    Code:
    static hasMany = [userRoles: UserRole]
    and generate views for UserRoles? Or is there some way I could have a more direct link to editing roles on the User edit page?

  • #2
    Don't add a hasMany for UserRole - the initially created User class has a method to retrieve that user's roles:

    Code:
    Set<Role> getAuthorities() {
       UserRole.findAllByUser(this).collect { it.role } as Set
    }
    The UI plugin (http://grails.org/plugin/spring-security-ui) has support for this. You could use that or just borrow the code.

    Comment


    • #3
      Originally posted by burtbeckwith View Post
      Don't add a hasMany for UserRole - the initially created User class has a method to retrieve that user's roles:

      Code:
      Set<Role> getAuthorities() {
         UserRole.findAllByUser(this).collect { it.role } as Set
      }
      The UI plugin (http://grails.org/plugin/spring-security-ui) has support for this. You could use that or just borrow the code.
      Using the grails generated view, with the existing getAuthorities method did show a list of authorities, but when I went to edit the user, I didn't see a way to edit them. (unless maybe i had broken something with my code changes).

      I will look into the ui plugin. I guess I was avoiding it since I have to make some customizations to security and wasn't sure how hard it would be to integrate those into the ui plugin vs just using default grails generated views.
      I have another post in spring security regarding some other problems I am having related to my security customizations. I wasn't sure which subforum to put it in.

      I was able to get something working before I read your reply:
      Code:
          static hasMany = [roles: Role]
      	static mapping = {
              roles joinTable: [name:"user_role", column:"role_id", key:"user_id"  ]
      	}
      //and commented out getAuthorities
      Is there a reason I should not do something this way? Sorry I am very new to grails and spring security and I'm a little overwhelmed.

      Comment


      • #4
        The motivation for mapping the join table with a domain class (UserRole) is to avoid the performance issues with mapped collections in Hibernate (and therefore GORM). Mapping just the roles side isn't that bad since a user won't have many roles, but making it bidirectional is quite expensive since popular roles will have many users. This solution works but it's unnecessary. Note that this is a Hibernate concern and has nothing to do with security.

        The most performant approach is to grant or deny a role to a user by adding or removing a row in the join table, which is exactly what happens when you create or delete a UserRole instance.

        If you don't want to use the UI plugin just copy the code from the user controller and views. The workflow for displaying roles and adding or removing them is already implemented there.

        Comment


        • #5
          Greetings Burt,

          First of all, congratulate you for your contributions. Are very valuable.

          I usually use the spring-security plugin-core, and have always had the same questions concerning UserRole entity.

          I have read what you say, which is optimal for hibernate ...

          But that gives me a headache and a question ...

          Headache:
          For queries, I tend to use the createCriteria, but if I want to find users that meet a condition for a certain role and that the result is paged, I find it complicated. I had to do it via HQL (which forces me to do an integration test, rather than a unit test ...)

          Question:
          If I wanted to use spring-security-core plugin with a NoSQL database (for example, dymanodb or mongodb), still applies what you comment about hibernate? Could I remove the domain UserRole? I should change spring-security config?

          What do you think? Thank you very much.

          Comment

          Working...
          X