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

Posted

技术标签:

【中文标题】我可以使用 Spring Security 管理多个浏览器选项卡吗?【英文标题】:Can I manage multiple browser tabs with Spring Security? 【发布时间】:2011-09-01 22:58:11 【问题描述】:

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

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

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

详情:我知道spring security,我只是在研究它。

现在感谢并原谅我的英语不好。

再见!

【问题讨论】:

【参考方案1】:

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

2.1.

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

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

【讨论】:

嗯,那么,我可以打开两个具有相同 JSESSIONID 的选项卡吗?太糟糕了。我想阻止 2 个标签。 2个浏览器都不是问题。有人知道另一种方式/框架/可以做到这一点吗?欢呼【参考方案2】:

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

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

【讨论】:

【参考方案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>

只要确保 login.jsp 上面的 javascript 不包括在内。

【讨论】:

以上是关于我可以使用 Spring Security 管理多个浏览器选项卡吗?的主要内容,如果未能解决你的问题,请参考以下文章

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

Vaadin 多用户会话管理

Spring security-完美权限管理系统(授权过程分析)

具有多租户架构的 Spring Security

Spring Security 入门(1-13)Spring Security - Session管理

spring security +MySQL + BCryptPasswordEncoder 单向加密验证 + 权限拦截 --- 心得