Grails Spring Security 插件 - 修改登录用户的权限
Posted
技术标签:
【中文标题】Grails Spring Security 插件 - 修改登录用户的权限【英文标题】:Grails Spring Security plugin - modify logged in user's authorities 【发布时间】:2011-09-18 13:38:23 【问题描述】:我有一个简单的 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 ,据我所知,默认情况下它是 false 。如果我错了,请纠正我。
编辑: 导致问题的顺序是
管理员“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”的身份“登录”,因此这不起作用。
非常欢迎任何想法。我可能在这里遗漏了一些简单的东西,但我不知道解决方案是什么。
干杯, 酣畅淋漓
【问题讨论】:
【参考方案1】:这是未经测试的,但请尝试一下
在您的控制器/服务类中,
...
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
【讨论】:
您好,感谢您的回复。在发布我的问题之前,我已经按照您的描述完成了。但是,这意味着如果您是管理员并且您更新了另一个管理员的权限 -> 然后调用 springSecurityService.reauthenticate user.username 将导致会话使用修改后的用户凭据进行更新。这意味着您刚刚以您修改的用户“登录”。我不希望这样 :) 我将编辑我的帖子,以更清楚地说明我在追求什么。 非常感谢,现在似乎工作正常,如此简单但非常强大! :) 虽然,确实应该有一些更简单的方法来通知修改后的用户在用户登录时他们的权限已更改。我需要深入了解这一点:) @mizzzto 没有问题!可能有一种更简单的方法来实现这一点......如果你发现了一些东西,请张贴出来! 理想的解决方案不是:SpringSecurityUtils.doWithAuth(otherUsername) springSecurityService.reauthenticate(otherUsername)
?似乎无法让它工作......【参考方案2】:
我已经通过两次重新认证解决了这个问题:
保存正在降级其他用户的管理员的名称:
def originalUserName = springSecurityService.principal.name
springSecurityService.reauthenticate user.username
springSecurityService.reauthenticate originalUserName
【讨论】:
以上是关于Grails Spring Security 插件 - 修改登录用户的权限的主要内容,如果未能解决你的问题,请参考以下文章
Grails,Spring Security LDAP 插件
在 grails 中使用 spring-security 插件时出错
使用 Spring Security Grails 插件编码密码
Grails - 卸载 Spring Security Core