0

我正在使用 CAS,刚刚从 3.4.8 更新到 3.5.1。我认为我已经处理了大部分的一千个变化。但是,完成后的 externalRedirect 似乎以某种方式被破坏了。它只是循环回到登录网络流的开始。这怎么可能发生?

这是达到的最终状态:

  <!-- The "redirect" end state allows CAS to properly end the workflow while 
    still redirecting the user back to the service required. -->
  <end-state id="redirectView"
    view="externalRedirect:${requestScope.response.url}" />

我知道它已经到达,因为我在这个方法(的org.springframework.webflow.action.ExternalRedirectAction)中设置了一个断点:

protected Event doExecute(RequestContext context) throws Exception {
    String resourceUri = (String) this.resourceUri.getValue(context);
    context.getExternalContext().requestExternalRedirect(resourceUri);
    return success();
}

如果我在此方法返回之前检查 resourceUri 的值,我会看到此请求应重定向到的 uri:

http://mycompany.com:8080/c/portal/login?redirect=%2Fweb%2Fguest%2Fhome&ticket=ST-4-jVOtEEZcy9bXdb4xiV3l-cas

但是,如果我只是从该断点运行,而不是被重定向到该页面,则相同的登录 Web 流程会重新开始。这里发生了什么?我应该去哪里看?关于调试的任何提示?

- - - - - - - - 更新 - - - - - - - -

所以在对代码进行了 0 次修改后,只需添加一些额外的断点,它现在就可以按预期工作了。我不知道这里发生了什么,但我终于找到了实际重定向发生的地方。对于那些感兴趣的人,重定向发生在:

org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handleFlowExecutionResult(
        FlowExecutionResult result, ServletExternalContext context,
        HttpServletRequest request, HttpServletResponse response, FlowHandler handler)
4

2 回答 2

2

看起来这个线程已经休眠了一段时间,但我想为将来可能出现的任何人提供一些信息。下面的解释来源于我对 CAS 4.0.1 的体验。如果这也不适用于旧版本,我会感到震惊......

首先要检查的是您的身份验证过程是否相对缓慢。例如,如果您是通过 VPN 链接或其他方式访问身份验证数据库的开发人员。或者,如果您的身份验证查询(和票证存储)相对较慢......

如果这适用于您,我在 CAS 中发现了一个问题,它以一种奇怪的方式与 Tomcat 交互,表现出上述行为。

CAS 中的问题在于称为 TerminateWebSessionListener 的 Web 流侦听器。这似乎是通过在流程完成后快速过期会话来保持低内存使用率的一种尝试。问题是,它的实现非常天真。它只是抓取会话并在其上设置 2 秒的“最大非活动间隔”(默认情况下 - 您可以使用timeToDieInSecondsTerminateWebSessionListener 中的属性更改此设置cas-servlet.xml。)

与 Tomcat 的交互是这样的:Tomcat在请求中第一次访问会话时标记会话的“最后访问”时间。但是,每次检索会话时,都会根据当前时间检查上次访问时间,以确定是否已过失效间隔。

所以发生的事情是 TerminateWebSessionListener 期望在那一刻之后HttpSession.setMaxInactiveInterval(2)导致会话无效 2 秒。它真正告诉 Tomcat 要做的是在当前请求中第一次访问会话后 2 秒使会话无效。如果您的身份验证/登录请求发生的时间超过 2 秒,BOOM!--下次有人在同一请求中请求它时,您的会话将无效。不幸的是,这确实发生在 Spring WebFlow 本身中。所以你在这里有一个竞争条件。

我将对此进行更多思考,并希望向 CAS 团队提出解决方案。同时,您可以禁用 TerminateWebSessionListener cas-servlet.xml,也可以将其timeToDieInSeconds提升到您期望的值,该值比完成身份验证请求所需的时间更长。30秒可能吗?这样做似乎是合理的。这似乎不是一种安全措施,只是一种节省内存的措施。

代码参考:

  • CAS 4.0.1
    • TerminateWebSessionListener.java:33 ( sessionEnded())
      • CAS 在这里设置会话失效间隔。
  • 雄猫 7.0.55:
    • Request.java:338(session实例变量。)
      • Tomcat 在其持续时间内将会话存储在请求中。
    • 请求.java:2899 ( doGetSession())
      • access()如果已经缓存在请求中,则会话提前返回。
    • 请求.java:2921 ( doGetSession())
      • 在请求中的第一次访问时,会在请求中查找、access()调用和缓存会话。

(注意:StandardSession.access()简单地用最后访问时间标记会话System.currentTimeMillis()。)

于 2015-01-31T21:01:03.313 回答
0

我发现了一些有用的东西。可能适用于您的特定问题,也可能不适用于您的具体问题。但是,如果您将此流程称为子流程,view则将忽略结束状态的参数。

但是,如果您只是正常调用此流程,它将执行重定向。解决此问题的方法是使用 aview-state而不是 a end-state。但这将使您保持流动和父母流动开放。

于 2012-11-29T19:19:01.297 回答