ViewExpiredException не генерируется при запросе ajax, если страница JSF защищена j_security_check - продолжение

-4

ViewExpiredException не выбрасывается на запрос ajax, если страница JSF защищена j_security_check, предоставляет решение, когда страница входа является страницей JSF. Но что, если страница входа в систему - это страница JSP?

У меня есть страница входа в jsp:

<login-config>
    <auth-method>FORM</auth-method>
    <form-login-config>
        <form-login-page>/core/login.jsp</form-login-page>
        <form-error-page>/core/login.jsp</form-error-page>
    </form-login-config>
</login-config>

На моей странице JSF (facelet), если я нажимаю кнопку не-Ajax, я буду перенаправлен на login.jsp. Если я нажму кнопку Ajax, он останется на той же странице JSF. Однако в обоих случаях код отладки, который я добавил на страницу входа в JSP, будет отображаться на консоли.

===

Я переписал страницу входа в систему, используя facelet вместо jsp

<login-config>
    <auth-method>FORM</auth-method>
    <form-login-config>
        <form-login-page>/facelets/login.jsf</form-login-page>
        <form-error-page>/facelets/login.jsf</form-error-page>
    </form-login-config>
</login-config>

Я добавил AjaxLoginListener:

public class AjaxLoginListener implements PhaseListener {

        @Override
        public PhaseId getPhaseId() {
    //        return PhaseId.ANY_PHASE;
            return PhaseId.RESTORE_VIEW;
        }

        @Override
        public void beforePhase(PhaseEvent event) {
            System.out.println("    **** AjaxLoginListener: Before Phase: " + event.getPhaseId());
            // NOOP.
        }

        @Override
        public void afterPhase(PhaseEvent event) {
            System.out.println("    **** AjaxLoginListener: After Phase: " + event.getPhaseId());
            FacesContext context = event.getFacesContext();
            HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
            String originalURL = (String) request.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI);
            String loginURL = request.getContextPath() + "/facelets/login.jsf";
            System.out.println("    **** "+new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                    + this.getClass().getName()+" AjaxLoginListener: After Phase: originalURL: " + originalURL + " Login URL: "+loginURL);
            System.out.println("    **** AjaxLoginListener: After Phase: request.getRequestURI() " +request.getRequestURI());

            System.out.println("    **** "+new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                    + this.getClass().getName()+" AjaxLoginListener: After Phase: isAjaxRequest " +context.getPartialViewContext().isAjaxRequest());

            if (context.getPartialViewContext().isAjaxRequest()
                    && originalURL != null
                    && loginURL.equals(request.getRequestURI()))
            {
                System.out.println("    **** "+new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                        + this.getClass().getName()+" AjaxLoginListener: After Phase: AjaxRequest " + event.getPhaseId());
                try {
                    context.getExternalContext().redirect(originalURL);
                } catch (IOException e) {
                    e.printStackTrace();
                    throw new FacesException(e);
                }
            }
        }
    }

Как только я использовал facelet вместо jsp, я смог вызвать слушателя. Тем не менее, он никогда не переходит на страницу входа, потому что originalURL (RequestDispatcher.FORWARD_REQUEST_URI) всегда имеет значение NULL для запросов Ajax. Что я делаю неправильно?

  • 0
    Просто отредактируйте loginURL соответственно? Что происходит, когда вы пытаетесь это сделать? Я не уверен, что понимаю вашу конкретную проблему. Обратите внимание, что я предполагаю, что вы абсолютно уверены, что у вас точно такая же проблема, как у ОП.
  • 0
    Я полагаю, что проблема заключается в том, как вы ее описали: «если бы страница входа не была страницей JSF (например, JSP или обычный HTML), то запрос ajax вернул бы весь вывод HTML страницы в виде ответа ajax, который JSF не разбирается ajax и интерпретируется как «пустой» ответ ». Я просто не могу понять, как перенаправить на страницу входа в этом случае.
Показать ещё 6 комментариев
Теги:
jsf-2
j-security-check
viewexpiredexception

1 ответ

0

Простым решением является добавление проверки, если пользователь вошел в систему, а если нет, для перенаправления на страницу входа:

    @Override
    public void afterPhase(PhaseEvent event) {
        System.out.println("    **** AjaxLoginListener: After Phase: " + event.getPhaseId());
        FacesContext context = event.getFacesContext();
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
        HttpSession session = request.getSession();

//        String originalURL = (String) request.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI);

        String loginURL = request.getContextPath() + "/facelets/login.dti";
        System.out.println("    **** "+new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName()+" AjaxLoginListener: After Phase:  Login URL: "+loginURL);
        System.out.println("    **** AjaxLoginListener: After Phase: request.getRequestURI() " +request.getRequestURI());

        System.out.println("    **** "+new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName()+" AjaxLoginListener: After Phase: isAjaxRequest " +context.getPartialViewContext().isAjaxRequest());

        if (context.getPartialViewContext().isAjaxRequest()
                && session.getAttribute("user") == null
                && loginURL.equals(request.getRequestURI()))
        {
            System.out.println("    **** "+new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                    + this.getClass().getName()+" AjaxLoginListener: After Phase: AjaxRequest " + event.getPhaseId());
            try {
                context.getExternalContext().redirect(loginURL);
            } catch (IOException e) {
                e.printStackTrace();
                throw new FacesException(e);
            }
        }

    }

Однако существенный недостаток здесь заключается в том, что после входа в систему он не пойдет на исходную страницу.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню