有点旧,但可能会为其他尝试团体的人提供帮助:
在用户类中:
Set<RoleGroup> getAuthorities() {
(UserRoleGroup.findAllByUser(this) as List<UserRoleGroup>)*.roleGroup as Set<RoleGroup>
}
Set<Role> getRoles() {
(UserRoleGroup?.findAllByUser(this)?.roleGroup?.authorities.collect{it}?.flatten() ?: oldRoles) as Set<Role>
}
List<String> getRoleNames() {
(UserRoleGroup?.findAllByUser(this)?.roleGroup?.collect{it.authorities.authority}?.flatten()?: oldRoles.authority) as List<String>
}
//Above will look up from userRoleGroup roleGroup.authorities = UserRole below
Set<Role> getOldRoles() {
(UserRole.findAllByUser(this) as List<Role>)*.role as Set<Role>
}
即使启用了组并针对旧的 oldRoles 方法进行身份验证,我也一直在使用角色:
import grails.plugin.springsecurity.userdetails.GormUserDetailsService
import grails.transaction.Transactional
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.Authentication
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.security.core.userdetails.UsernameNotFoundException
class MySpringSecurityAuthenticator extends GormUserDetailsService{
UserDetails loadUserByUsername(String username, boolean loadRoles)
throws UsernameNotFoundException {
return loadUserByUsername(username)
}
@Transactional
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//enable login with either username or password
User user = User.find {
username == username || attributes.emailAddress == username || userCode == username
}
//if (!user) throw new UsernameNotFoundException('User not found', username)
if (!user) throw new UsernameNotFoundException('User not found')
return loadUserByUsername( user)
}
@Transactional
UserDetails loadUserByUsername(User user) throws UsernameNotFoundException {
if (!user) throw new UsernameNotFoundException('User not found')
//UserDetails.withNewSession {
//getAuthorities(user.oldRoles)
UserDetails userDetails = new org.springframework.security.core.userdetails.User(user.username, user.password,
user.enabled, !user.accountExpired, !user.passwordExpired, !user.accountLocked,getAuthoritiesFromGroup(user.authorities) )
Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities())
SecurityContextHolder.getContext().setAuthentication(authentication)
return userDetails
//}
}
public static List<GrantedAuthority> getAuthoritiesFromGroup(Set<RoleGroup> roles) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>()
roles?.each { role ->
println "-- role = ${role} vs ${role.getClass()}"
authorities.add(new SimpleGrantedAuthority(role.name))
}
return authorities
}
public static List<GrantedAuthority> getAuthorities(Set<Role> roles) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>()
roles?.each { role ->
println "-- role = ${role} vs ${role.getClass()}"
authorities.add(new SimpleGrantedAuthority(role.authority))
}
return authorities
}
}
在我的 spring/resources.groovy 中:
userDetailsService(MySpringSecurityAuthenticator){
grailsApplication = ref('grailsApplication')
}
到目前为止,上面所做的是回到用户 ROLES 并通过..getAuthorities(user.oldRoles) 将它们添加到身份验证处理程序
我现在已将上述方法更改为通过 getAuthoritiesFromGroup(user.authorities) 读取组名
这只是解析组名,作为我正在使用的版本的一个副作用(效果)还必须包含单词 ROLE_GROUPNAME
所以现在如果创建
@Transactional
def grantPermission(User user, String role='ROLE_ADMIN', String group='ROLE_SUPERGROUP') {
def adminRole = Role.findByAuthority(role)
if (!adminRole) {
adminRole = new Role(authority: role).save(flush: true)
}
UserRole.create user, adminRole, true
def adminRoleGroup = RoleGroup.findByName(group)
if (!adminRoleGroup) {
adminRoleGroup = new RoleGroup(name: group).save(flush: true)
}
def adminRoleGroupRole = RoleGroupRole.findByRole(adminRole)
if (!adminRoleGroupRole) {
adminRoleGroupRole = new RoleGroupRole(role: adminRole, roleGroup: adminRoleGroup).save(flush: true)
}
def alreadyDone = UserRoleGroup.findByUserAndRoleGroup(user,adminRoleGroup)
if (!alreadyDone) {
new UserRoleGroup(user: user, roleGroup: adminRoleGroup).save(flush: true)
}
}
我希望根据组名而不是用户角色进行身份验证,所以简而言之,我不得不将我的控制器更改为
@Secured("hasAnyRole('ROLE_SUPERGROUP')")
希望它是有意义的,应该是直截了当的,只是需要时间来理解这一切..
在这一点上,我仍在玩弄,我不会将其用作具体答案,因为我有点想将其添加为我的权限,如果我愿意,我可以添加另一个钩子以进一步了解这些团体中的每一个以及其中的每个实际角色 - 不确定会产生什么 - 目前
我想将其更改为 requestMaps 并将其移至 db 进行大量更改并将决定我是否应该恢复或使用我知道的组,这样我可以在控制器上配置更少的名称并依赖组名称。 .
无论哪种方式,它都在这一切的背后,并在几年后为您提供一个清晰的想法,但可能对其他人派上用场
更新
所以我决定去:
,getAuthorities(user.roles)
上述代码中的Set<Role> getRoles() {方法
原因很简单:
results?.each {
it.user=User.get(it.id)
println "-- \n${it.id}:${it.user.roles} \n${it.id}:${it.user.oldRoles}"
7:[Role(authority:ROLE_ADMIN), Role(authority:ROLE_ADMINAHHA)]
7:[Role(authority:ROLE_ADMIN)]
如您所见,我使用 getOldRoles 添加了一个新用户我在 getRoles 上只看到 1 个角色我得到了 2 个角色..我确实添加了具有 2 个角色的用户..
所以现在这将解析所有用户角色并将它们添加到List<GrantedAuthority> 身份验证仍将通过之前生成的实际角色名称进行。
这只是意味着当我从用户禁用一个组时,这应该停止为该用户加载该权限..
这就是模型应该做的事情