我有一个简单的Grails应用程序,安装了Spring Security Core插件,工作正常。但是,我没有找到任何解决方案来更新安全上下文中登录用户的权限。我不是在谈论更新当前用户的详细信息(即springSecurityService.reauthenticate)。
我的问题是:我有一个简单的用户管理应用程序,使用了ROLE_ADMIN和ROLE_USER权限。现在,我有2名管理员同时从不同的计算机登录(具有ROLE_ADMIN权限),并且一名管理员决定将其他管理员的权限从ROLE_ADMIN更改为ROLE_USER。
如何更新用户和角色,以便修改后的用户(具有新的ROLE_USER角色)无法执行任何ROLE_ADMIN级别操作,并立即重定向到ROLE_USER级别页面?有没有办法更新安全上下文,所以我不必在所有控制器操作中进行额外检查,无论登录用户的权限是否已更改?我能以某种方式使用cahceUsers属性吗?我没有修改cacheUsers,根据我的理解,默认情况下它是假的。如果我错了,请纠正我。
编辑: 导致问题的顺序是
管理员“A”修改管理员“B”并为管理员“B”设置新角色(ROLE_USER)
代码调用PersonRole.removeAll(personInstanceB) and
PersonRole.create(personInstanceB, roleAdmin)
,所有内容都正常更新
同时管理员“B”在修改其权限时已经登录。管理员“B”可以继续处理ROLE_ADMIN受限页面,直到他/她注销并进行新登录。只有这样才能更新权限并且管理员“B”具有新角色(ROLE_USER)
我希望管理员“B”在使用新角色更新用户时重定向到ROLE_USER页面,而不仅仅是在注销/登录后
调用springSecurityService.reauthenticate personInstanceB.username)
会导致管理员“A”以管理员“B”“登录”,因此无效。
任何想法都会非常受欢迎。我可能在这里错过了一些简单的东西,但我不知道解决方案会是什么。
干杯, mizzzto
答案 0 :(得分:11)
这是未经测试但尝试一下
在您的控制器/服务类中,
...
User user = User.get(springSecurityService.principal.id) //get the user
Role adminRole = //get or create the admin Role
UserRole.remove user, role // remove admin Role
Role userRole = // get or create the user Role
UserRole.create user, role //add the user Role
...
if (!user.hasErrors() && user.save(flush: true)) {
springSecurityService.reauthenticate user.username // refresh the users security deatils
}
....
现在更清楚了。
我要做的就是使用切换用户功能。见Switch User
useSwitchUserFilter
属性设置为true
ROLE_SWITCH_USER
)。在你的管理页面中,
<sec:ifAllGranted roles='ROLE_SWITCH_USER'>
<form action='/j_spring_security_switch_user' method='POST'>
Switch to user: <input type='text' name='j_username'/> <br/>
<input type='submit' value='Switch'/>
</form>
</sec:ifAllGranted>
adminToUser()
方法(例如)- 您可以使用第一个答案的代码在控制器或服务中创建一个方法,该方法接受userInstance并将其角色从管理员更改为用户。
def adminToUser(user, adminRole, userRole){
UserRole.remove user, adminRole
UserRole.create user, userRole
if (!user.hasErrors() && user.save(flush: true)) {
springSecurityService.reauthenticate user.username
}
}
答案 1 :(得分:6)
我通过重新验证两次解决了这个问题:
保存正在降级其他用户的管理员的姓名:
def originalUserName = springSecurityService.principal.name
springSecurityService.reauthenticate user.username
springSecurityService.reauthenticate originalUserName