Spring切换用户:仅允许具有特定角色的用户切换到具有特定角色的其他用户

时间:2012-02-02 08:55:48

标签: java security spring spring-mvc spring-security

我正在使用Spring Security制作一个具有3种不同角色的Web应用程序:

  • SuperSupporter
  • DivisionSupporter
  • 客户端

目前我的应用程序允许SuperSupporter使用SwitchUserFilter “冒充”DivisionSupporter,让他充当该DivisionSupporter。如果DivisionSupporter遇到一些问题 - 并且需要支持,这是必要的。这可能听起来很奇怪,但它有点使用TeamViewer来检查朋友的计算机问题。

此外,现在我们需要赋予 DivisionSupporter “模仿”客户端的权利,以便DivisionSupporter可以“支持”客户端。

但令我担心的是,如果我们授予 DivisionSupporter 访问j_spring_security_switch_user的权利,恶意的DivisionSupporter可能会使用它来模仿SuperSupporter(通过发布到链接用户名)。

我想到了解决这个案子的工作:

 <bean id="switchUserFilter" class="org.springframework.security.web.authentication.switchuser.SwitchUserFilter">
        <property name="userDetailsService" ref="userDetailsService" />
        <property name="switchUserUrl" value="/j_spring_security_switch_user" />
        <property name="exitUserUrl" value="/j_spring_security_exit_user" />
        <property name="targetUrl" value="/checkRole.html" />
     </bean>

/checkRole动作(targetUrl)中,我再次检查:如果用户角色是SuperSupporter并且他冒充某人,则应用程序会将他发送给/j_spring_security_exit_user(因为SuperSupporter赢了不需要冒充 自己)。

虽然它似乎有用,但我担心恶意用户可能会找到解决此问题的方法,从而使我们的系统处于危险之中。

我认为SpringSecurity可能已经解决了这个需求,但仍无法找到它。这种方式真的很安全吗? DivisionSupporter可以使用我当前的解决方案来模拟SuperSupporter吗?

更重要的是,有没有更好的方法来解决这个问题?

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:6)

targetUrl方法不是一个好主意,因为用户可以忽略重定向并请求另一个URL。您需要首先防止不适当的开关。

您最好的选择可能是在attemptSwitchUser上自定义SwitchUserFilter方法:

protected Authentication attemptSwitchUser(HttpServletRequest request) {
    Authentication switchTo = super.attemptSwitchUser(request);
    Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
    // Inspect currentUser (e.g. authorities) and switchTo to see if valid combination
    // Raise AuthenticationException if not

    return switchTo;
}

SecurityContext设置之前调用该方法,因此它是检查交换机有效性的最佳位置。

答案 1 :(得分:0)

使用以下example使用Spring Security切换用户。

本节设置应用此功能的主要参数:

@Bean
public SwitchUserFilter switchUserFilter() {
    SwitchUserFilter filter = new SwitchUserFilter();

    filter.setUserDetailsService(defaultUserDetailsService);
    filter.setTargetUrl("/");
    filter.setSwitchUserUrl("/switchuserto");
    filter.setUsernameParameter("username");
    filter.setExitUserUrl("/switchuserlogout");
    filter.setSwitchFailureUrl("/index");

    return filter;
}

以下字符串将switchUserFilter对象添加到HttpSecurity http对象:

.addFilter(switchUserFilter())