我可以使用Spring Security管理多个浏览器选项卡吗?

时间:2011-05-25 17:01:33

标签: java jsf spring-security

我想知道,使用Spring Security,我可以验证用户会话,只允许打开一个浏览器选项卡。有可能吗?

我还想知道我是否可以这样做,当用户关闭选项卡并在会话结束之前再次打开它时,直接从应用程序进入SessionFilter,而无需进入登录屏幕。

我正在使用JSF 1.2,RichFaces 3.3.3,Hibernate和co ...

细节:我知道春天的安全,我只是在研究它。

现在谢谢我的英语不好。

见啊!

3 个答案:

答案 0 :(得分:5)

没有。 Spring Security无法判断请求是来自原始选项卡还是来自新选项卡 - 该信息严格来自客户端。来自http://static.springsource.org/spring-security/site/faq.html

  

2.1。

     

我正在使用Spring Security的并发   会话控制,以防止用户   一次登录多次。   当我打开另一个浏览器窗口时   登录后,它不会阻止我   从登录再次。我为什么要登录   不止一次?

     

浏览器通常只保留一个   每个浏览器实例的会话您   不能有两个单独的会议   一旦。所以,如果你再次登录   另一个窗口或标签你就是   在同一会话中重新认证。   服务器什么都不知道   标签,窗口或浏览器实例。   它看到的只是HTTP请求和它   将这些与特定会话联系起来   根据的价值   它们包含的JSESSIONID cookie。   当用户在a期间进行身份验证时   会话,Spring Security的并发   会话控制检查的数量   他们认证的其他认证会话   有。如果他们已经   使用相同的会话进行身份验证,   然后重新认证将没有   效果。

答案 1 :(得分:3)

我最近使用Spring Security实现了多个选项卡/窗口的解决方案。为了成功登录,我使用`LoginSucessHandler``并在会话中设置一个唯一的窗口名称。在主模板页面上,我设置了一个窗口名称,并在每个页面上加载验证窗口名称和会话的窗口名称,如果它不相同,则重定向到错误页面。

以下是配置和代码:

@Service
public class LoginSucessHandler extends
        SavedRequestAwareAuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
            HttpServletResponse response, Authentication authentication)
            throws ServletException, IOException {
        User user = (User) authentication.getPrincipal();
        String windowName = user.getUsername() + new Date().getTime();
        HttpSession session = request.getSession();
        session.setAttribute("windowName", windowName);
        session.setAttribute("windowNameToSet", windowName);
        super.onAuthenticationSuccess(request, response, authentication);
    }

}

主模板或标题页:

<script>
  <%if (session.getAttribute("windowNameToSet") != null) {
        out.write("window.name = '"
            + session.getAttribute("windowNameToSet") + "';");
        session.removeAttribute("windowNameToSet");
  }%>
  if (window.name != "<%=session.getAttribute("windowName")%>") {
        window.location = "<%=request.getContextPath()%>/forms/multiwindowerror.jsp";
  }
</script>

对于安全上下文:

<http auto-config="true" use-expressions="true">
    <intercept-url pattern="/login.hst**" access="anonymous or authenticated" />
    <intercept-url pattern="/**/*.hst" access="authenticated" />
    <form-login login-page="/login.hst"
        authentication-failure-url="/login.hst?error=true"
        authentication-success-handler-ref="loginSucessHandler" />
    <logout invalidate-session="true" logout-success-url="/home.hst"
        logout-url="/logout.hst" />
    <remember-me key="jbcp" authentication-success-handler-ref="loginSucessHandler"/>
</http>

请确保不包含JavaScript上面的login.jsp。

答案 2 :(得分:2)

我想出了一种更简单的方法来完成同样的事情。如果您已经扩展SimpleUrlAuthenticationSuccessHandler,类似于@Jagar,请创建登录用户的arraylist,将用户添加到其中,然后将其添加到会话中。然后,每次登录时,检查会话是否存在以及该用户是否在会话arraylist属性中。如果是,则失败,如果不是,则允许登录。

这样,您可以让多个用户使用相同的浏览器登录,但不能使用同一个用户。这也可以防止错误覆盖windowName属性的可能性。