1
votes

In my project certain users have dual roles, so if any such user logs in how can I make him switch between those 2 ROLES he has so that he can perform certain operations which that particular ROLE provides.

Appreciate step by step process as I am really new to Grails. Any such literature online with example is highly appreciated.

UPDATE:- WorkridersUser loadUserByUsername(String username, String roleName) throws UsernameNotFoundException { // def conf = SpringSecurityUtils.securityConfig //Class User = grailsApplication.getDomainClass("Person").clazz

    SchemeUser.withTransaction { status ->

        SchemeUser user = SchemeUser.findByUsername(username) 
        if (!user){ throw new UsernameNotFoundException('User not found', username)}

        UserProfile userProfile = UserProfile.findByEmail(user.username)
        Representative representative = Representative.findByUser(user)
        Organization organization = Organization.get(representative.organization.id)


        def authorities = user.authorities.collect {new GrantedAuthorityImpl(it.authority)}

        return new WorkridersUser(user.username, user.password, user.enabled, 
            !user.accountExpired, !user.passwordExpired, !user.accountLocked, 
            authorities ?: roleName, user.id, organization.companyName,userProfile) 
    } 
}

Thanks

Sri

2
Burt Beckwith, I am looking forward to your reply ;)srisris
If user have two roles, that means that she already have access to both operations, why you need to switch between roles?Igor Artamonov
e.g. I have these roles, Employer,Employee and a Representative. Since Employer cannot act himself he needs a Representative on its behalf. But Representative is also an Employee of that particular Employer, so I want to switch between Representative & Employee types of roles. When logged in as Representative he can approve or reject certain transactions, but being an Employee he doesnt have that capability. Hence I needed to switch. Appreciate any idea how to implement thissrisris
is she having both roles at same time?Igor Artamonov
I can't understand this problem. If your user have Employer role - it have access to resources for this role, if she have role Representative - access to representative resources. As she have both roles at same time - she have access to any of this resource, at same time. Isn't it?Igor Artamonov

2 Answers

2
votes

you need to override the loadUserByUsername method as follows:

UserDetails loadUserByUsername(String username, String selectedRole) {
  // current selected role is stored in the member variable of the UserDetail class         
  this.selectedRole = selectedRole
  return loadUserByUsername(username)
}

to show all roles of current user within a select box write your own tag lib which should look like:

def authorities = springSecurityService.principal.originalAuthorities
if (authorities.size() > 1) {
    out << "<form name='switchRoleForm' action='switchRole' method='post'>"
    out << "<select name='roles'>"
    Role tmpRole
    authorities.each {
        tmpRole = Role.findByAuthority(it.authority)
        // access your current select role
            if (springSecurityService.principal.selectedRole== it.authority)
            out << "<option selected value='${it.authority}'>${tmpRole.name}</option>"
        else
            out << "<option value='${it.authority}'>${tmpRole.name}</option>"
    }
    out << "</select>"
    out << '<input class="switch" type="submit" value="switch"/></span>'
    out << "</form>"        
}

i described the switch logic in previous post.

2
votes

first of all you have to implement your own user details class and serivce. http://burtbeckwith.github.com/grails-spring-security-core/docs/manual/index.html. Within your own UserDetailsService you can motify the authorities property in the loadUserByUsername method, so that this property contains only one role at the same time. then you can switch between roles by modifying this property agian. for example

// imagine the following code would be in your switch controller action
// fetch your user detail service bean (registered via resources.groovy and not as a service)
UserDetailsService userDetailsService = grailsApplication.mainContext.getBean("userDetailsService");
UserCache userCache = grailsApplication.mainContext.getBean("userCache");
// update authorities in user details. only one role should exists in authorities list
UserDetails userDetails = userDetailsService.loadUserByUsername(springSecurityService.principal.username, <place here the rolel to switch>);
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(),userDetails.getAuthorities()));
// refresh user detail
userCache.removeUserFromCache(springSecurityService.principal.username);