6

在我之前的工作中,我遇到了一个众所周知的问题,即无法阻止用户在注销后使用返回按钮浏览网站。我的技术包括 Spring、JavaScript 和可能的 Java AJAX 库 ZK 的 Mobile 模块。除了使用后退按钮导航之外,授权访问还可以正常工作。我不再有权访问应用程序代码。该应用程序是一个移动应用程序,我不是其中的原作者。

我尝试了以下常见解决方案:


我们在 中有以下定义t2-spring-security-context.xml

<http auto-config="true">
    <intercept-url pattern="/mobile-index*" access="ROLE_ADMIN"/>
    <intercept-url pattern="/t2-metrics*" access="ROLE_ADMIN"/>
    <intercept-url pattern="/t2-monitor*" access="ROLE_ADMIN"/>
    <form-login login-page="/login.jsp" authentication-failure-url="/loginerror.jsp"
                default-target-url="/mobile-index.jsp"/>
    <logout logout-success-url="/login.jsp" invalidate-session="true"/>

</http>


关于我们实施的其他细节:

  • @RequestMapping使用注释为的类从 JavaScript调用 Java 方法@Controller(IE t2-metrics.jsp 有 JS 触发到 URL 匹配请求映射)
  • 尝试将security:global-method-security应用程序上下文和角色注释添加到方法
  • 有 scriptlet 代码来禁用对 JSP 页面的缓存,但什么也没做。此外,在 IntelliJ 中的调试中启动了应用程序,并且未命中我定义的过滤器中的调试点。
  • 一旦他们使用后退按钮返回到应用程序,用户仍然可以在应用程序中导航。

我唯一剩下的想法是问题涉及我们的客户端代码(JavaScript)或库(与 Spring Security 的不正确集成),因为调试没有命中 Spring Security 过滤器链。

4

4 回答 4

9

在 servlet-context 文件中使用以下代码

    <mvc:interceptors>
        <bean id="webContentInterceptor" class="org.springframework.web.servlet.mvc.WebContentInterceptor">
                <property name="cacheSeconds" value="0"/>
                <property name="useExpiresHeader" value="false"/>
                <property name="useCacheControlHeader" value="true"/>
                <property name="useCacheControlNoStore" value="true"/>
            </bean>     
        </mvc:interceptors>

它将与 jsp 页面中的以下代码相同:

  response.setHeader("pragma", "no-cache");              
  response.setHeader("Cache-control", "no-cache, no-store, must-revalidate");             
  response.setHeader("Expires", "0"); 
于 2013-06-19T12:24:55.233 回答
2

您是否直接渲染视图(JSP)?

如果是这样,请将 no-cache 指令直接添加到 JSP:

<% response.setHeader("Cache-Control", "no-cache"); %>
...

另一个(首选)选项是防止直接访问 JSP 并通过控制器呈现它们:

@RequestMapping(value = "/login", method = GET)
public String renderLoginPage() {
    return "login";
}

用这个来按名称解析视图(从控制器方法返回的字符串):

<bean
    id="viewResolver"
    class="org.springframework.web.servlet.view.InternalResourceViewResolver"
    p:prefix="/WEB-INF/views" p:suffix=".jsp"
/>

/WEB-IBF/views/login.jsp作为视图。

使用后一种方法允许您使用该WebContentInterceptor方法很好地防止缓存。

还要确保所有请求都命中 Spring 安全过滤器链。

于 2013-05-29T19:38:54.357 回答
0

不幸的是,我不能再回到这段代码来解决我们在这里所做的阻止我们得到这个问题的答案的事情。不过,开发人员可以创造出令人困惑的东西来迷惑自己。

尽管我认为这是答案(尚待证明),但其他答案也是有用的(值得赞成),还有这个。我当时认为的解决方案是前端代码,而不是使用Spring Security 过滤器可以管理的诸如 MVC之类的Spring构造,我们可能使用了 Spring 的调度程序(请参阅此处的文档)并以某种方式绕过过滤器技术,我记得,对于实现Spring Security至关重要。

我将尝试发布一些前端代码来演示我们调用 REST 服务的方式,并证明我们绕过了 Spring Security。

如果您不同意,请随时与我联系。

于 2013-12-19T12:06:19.493 回答
0

我们不使用 Spring 安全性,所以我不熟悉它的所有配置属性,但如果我是你,我会从研究浏览器缓存问题开始。应该很容易测试......(1)点击后退按钮后强制重新加载页面,或者(2)注销后,清除浏览器缓存(不是cookie),然后点击后退按钮。如果这会导致所需的行为,那么下一步应该包含 HTTP 响应标头属性来控制浏览器缓存。

如果不是这样,那么我将不知道在您的 Spring 安全配置中寻找什么。希望其他人可能知道答案。

编辑:刚刚发现另一个类似的问题,确认浏览器缓存问题部分 - 该问题的答案包含他们用于设置响应标头的机制,以防万一这对您有帮助 - Spring Security Logout Back Button

于 2013-05-29T16:57:14.990 回答