2011-06-20 67 views
7

我有一个简单的Grails应用程序,安装了Spring Security Core插件,工作正常。但是,我还没有找到任何解决方案来更新安全上下文中登录的用户权限。我不是在谈论更新当前用户的详细信息(即springSecurityService.reauthenticate)。Grails Spring Security插件 - 修改已登录的用户权限

我的问题是:我有一个简单的用户管理应用程序,使用ROLE_ADMIN和ROLE_USER权限。现在,我有两个管理员从不同的计算机同时登录(具有ROLE_ADMIN权限),一个管理员决定将另一个管理员的权限从ROLE_ADMIN更改为ROLE_USER。

如何更新用户和角色,以便修改的用户(具有新的ROLE_USER角色)不能执行任何ROLE_ADMIN级别的操作并立即重定向到ROLE_USER级别的页面?有没有办法更新安全上下文,所以我不必在所有控制器操作中进行额外检查,无论登录用户的权限是否已更改?我能以某种方式使用cahceUsers属性吗?我没有修改cacheUser,并且我的理解是默认为false。请纠正我,如果我错了。

编辑: 是造成该问题的顺序是

  1. 管理员 “A” 修改管理员 “B”,并设置一个新的角色(ROLE_USER)管理员 “B”

  2. 代码调用PersonRole.removeAll(personInstanceB) and PersonRole.create(personInstanceB, roleAdmin)并且所有内容都正常更新

  3. 同时管理员“B”已在其权限被修改时登录。管理员“B”可以继续在ROLE_ADMIN受限制页面上工作,直到他/她注销并执行新的登录。只有当时权限更新和管理员“B”具有新角色(ROLE_USER)

  4. 我希望管理员“B”被重定向到ROLE_USER页面,当用户更新新角色时不仅注销后/ login

  5. 致电springSecurityService.reauthenticate personInstanceB.username)导致管理员“A”以管理员“B”身份登录,因此这不起作用。

任何想法都会非常受欢迎。我可能错过了一些简单的东西,但我不知道解决方案是什么。

干杯, mizzzto

回答

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并改变从管理员用户thier作用。

def adminToUser(user, adminRole, userRole){ 
    UserRole.remove user, adminRole 
    UserRole.create user, userRole 
    if (!user.hasErrors() && user.save(flush: true)) { 
     springSecurityService.reauthenticate user.username 
    } 
} 
+0

您好,感谢答复。在发布我的问题之前,我已经按照你所描述的完成了。但是,这意味着如果您是管理员并且您更新了另一个管理员的权限 - >那么调用springSecurityService.reauthenticate user.username将会使用修改的用户凭证更新会话。这意味着您刚刚以您所修改的用户“登录”。我不希望那样:)我会编辑我的帖子,使之更清楚我后面的内容。 – mizzzto

+0

@mizzzto看编辑! – gotomanners

+0

非常感谢,似乎现在工作得很好,很简单,但非常强大! :)虽然,真的应该有一些更简单的方式来通知修改后的用户,他们的权限在用户登录时已被更改。我需要深入此:) – mizzzto

6

我已经两次重新验证解决了这个问题:

保存谁是降级的其他用户的管理员名称:

def originalUserName = springSecurityService.principal.name 
springSecurityService.reauthenticate user.username 
springSecurityService.reauthenticate originalUserName 
相关问题