首页 > 解决方案 > 在 Wicket 9 中,当用户的会话在某些页面中过期时,他们会被重定向到登录页面而不是 Session Expired 页面

问题描述

在将一些遗留代码从 Wicket 1.5 升级到 Wicket 9 时,我发现重定向到“会话已过期”通知页面似乎被部分破坏了。

我在主应用程序文件中有以下语句,它以前总是可以工作:

getApplicationSettings().setPageExpiredErrorPage(MyErrorPage.class);

这是应该触发重定向到“MyErrorPage”的场景:

  1. 用户成功登录并进入任何菜单选项。
  2. 他们坐了一会儿,什么也不做,他们的会话超时。
  3. 在这段不活动之后,他们单击链接或尝试提交表单。
  4. 此时,它们应该被重定向到“MyErrorPage”。

在点 (1) 中调用的菜单选项 - 让我们称之为 MyMenuPage - 可以使用两种可能的语法类型调用:

setResponsePage(MyMenuPage.class);

或者:

setResponsePage(new MyMenuPage(params));

如果使用 SECOND 语法调用原始菜单页面,用户似乎只会被重定向到我的自定义错误页面。

如果原始页面是使用 FIRST 语法调用的,则用户会被直接发送到登录页面,而不会对他们的页面已过期的事实进行任何解释。

请有人告诉我如何在两种类型的页面中获得相同的结果 - 这不是无状态的,因为用户已经登录。

标签: javasessiontimeoutwicketexpired-sessions

解决方案


页面过期和 http 会话过期是有区别的。

正如 PageExpiredException 的 javadoc [I] 解释的那样,有三个可能的原因:

  • 该页面从未存储在那里,例如在存储过程中发生错误
  • http 会话已过期,因此与此会话相关的所有页面也将被删除
  • 由于超出了存储大小,页面实例已被删除

Wicket 将所有有状态的页面存储在磁盘上。稍后当您使用此类页面时,例如通过单击链接,Wicket 会加载页面实例、执行单击并呈现响应。

如果 http 会话已过期,那么很可能您的身份验证策略会启动并重定向到登录页面,甚至无需尝试加载旧页面。如果您Component#continueToOriginalDestination()在成功登录后使用,则用户将被导航到旧页面的新实例。

总结一下:

  • 如果 http 会话过期,那么您的应用程序将重定向到 LoginPage
  • 如果页面实例已过期,则默认情况下,Wicket 将创建它的新实例(请参阅PageSettings#setRecreateBookmarkablePagesAfterExpiry(boolean))或显示配置的getApplicationSettings().setPageExpiredErrorPage(MyPage.class);将被呈现

要调试在您的情况下发生的事情,请在以下位置放置一些断点:

  1. https://github.com/apache/wicket/blob/6a7e4c3d770324f125fbf43615c7708b67c8d8c5/wicket-core/src/main/java/org/apache/wicket/Component.java#L1061
  2. https://github.com/apache/wicket/blob/6a7e4c3d770324f125fbf43615c7708b67c8d8c5/wicket-auth-roles/src/main/java/org/apache/wicket/authroles/authentication/AuthenticatedWebApplication.java#L134

一、https://github.com/apache/wicket/blob/master/wicket-core/src/main/java/org/apache/wicket/protocol/http/PageExpiredException.java#L31


推荐阅读