【问题标题】:Display message to user on expired session when using wicket-auth-roles使用 wicket-auth-roles 时在过期会话上向用户显示消息
【发布时间】:2014-03-24 15:41:54
【问题描述】:

您好,我在 Wicket 6.* 中无法解决以下问题:

在我们的 web 应用中,我们使用 wicket-auth-roles 来管理身份验证/授权。当会话到期时,用户应该在他的下一个动作中被重定向到getApplicationSettings().setPageExpiredErrorPage(SomePage.class) 设置的页面。但是,如果用户尝试访问不允许访客访问的页面,则会被重定向到完全跳过 PageExpiredPage 的登录页面。

我的问题是 - 如何显示“会话已过期”。向用户发送消息?

除其他外,我在会话生命周期的onInvalidate 阶段尝试了session.info("message"),但是反馈消息随后会在登录后的第一页上呈现(而不是在登录页面上)。

感谢您的回答。

【问题讨论】:

    标签: session wicket session-timeout wicket-1.6


    【解决方案1】:

    您可以使用RequestCycleListener 记录何时抛出PageExpiredException

    public class ExceptionMapperListener extends AbstractRequestCycleListener {
    
        @Override
        public IRequestHandler onException(RequestCycle cycle, Exception ex) {
            if (ex instanceof PageExpiredException) {
                // Record in session or request cycle
                // OR
                // Create a RenderPageRequestHandler yourself and add a page parameter
                // See DefaultExceptionMapper#internalMap(Exception)
            }
            return null;
        }
    }
    
    // In Application#init():
    getRequestCycleListeners().add(new ExceptionMapperListener());
    

    原始答案

    (保留,因为它仍然可以提供帮助......)

    我自己没有尝试过,因为我不使用 wicket-auth-roles,但尝试用类似这样的东西覆盖方法 AuthenticatedWebApplication#restartResponseAtSignInPage()

    if (isSessionExpired()) {
        PageParameters params = new PageParameters();
        params.add("showSessionExpired", true);
        throw new RestartResponseAtInterceptPageException(getSignInPageClass(), params);
    } else {
        throw new RestartResponseAtInterceptPageException(getSignInPageClass());
    }
    

    然后在 SignInPageClass 中,如果存在 showSessionExpired 页面参数,则显示所需的消息。

    我不确定您如何实现 isSessionExpired(),但您似乎已经涵盖了这部分内容。

    根据您实现isSessionExpired() 的方式,也许您可​​以在您的SignInPageClass 中执行以下操作:

    if (sessionExpired()) {
        session.info("message")
    }
    

    【讨论】:

    • 不幸的是,isSessionExpired() 正是我被卡住的部分。我无法判断当前会话是 new 还是 new after the previous one expiresAuthenticatedWebApplication 类中。
    • 你的更新让我走上了正确的道路,我想。我需要实现RequestCycleListeneronBeginRequest(RequestCycle cycle),我可以在其中检查请求的会话有效性。我仍然需要弄清楚的唯一问题是如何区分过期会话和故意无效的会话(例如,当用户注销时)。我解决后会提供更多信息。
    【解决方案2】:

    bernie 让我走上正确的道路后,我终于找到了解决问题的方法:

    首先需要覆盖RequestCycleListener

    public class SessionExpiredListener extends AbstractRequestCycleListener {
      public void onRequestHandlerResolved(RequestCycle cycle, IRequestHandler handler) {
        if (handler instanceof IPageRequestHandler) {
            IPageRequestHandler pageHandler = (IPageRequestHandler) handler;
    
            HttpServletRequest request = (HttpServletRequest) cycle.getRequest().getContainerRequest();
    
            //check whether the requested session has expired
            boolean expired = request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid();
    
            //check whether the requested page can be instantiated with the current session
            boolean authorized = Session.get().getAuthorizationStrategy().isInstantiationAuthorized(pageHandler.getPageClass());
    
            if (expired && !authorized) {
                throw new PageExpiredException("Session has expired!");
            }
    
        }
        super.onRequestHandlerResolved(cycle, handler);
      }
    }
    

    检查authorized 可防止在注销或访问未受保护的页面时显示会话过期消息。

    最后,您必须在您的WebApplication 中注册您的听众和PageRequestHandlerTracker

    getRequestCycleListeners().add(new SessionExpiredListener());
    getRequestCycleListeners().add(new PageRequestHandlerTracker());
    

    【讨论】:

      猜你喜欢
      • 2017-02-07
      • 2021-08-08
      • 2012-05-28
      • 1970-01-01
      • 2018-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-25
      相关资源
      最近更新 更多