Частичный ответ по истечении сеанса


У нас есть приложение JSF 2.0, Primefaces 5.0, Spring Security 3.2.3.RELEASE.
Чтобы обработать тайм-аут сеанса, я использую простые лица idleMonitor и p:dialog & javascript для отображения всплывающего окна обратного отсчета и перенаправления их обратно на страницу входа.
Я также реализовал пользовательский CacheControlPhaseListener, чтобы страницы не кэшировались. Я установил no-cache в заголовках ответа в CacheControlPhaseListener.

<lifecycle><phase-listener id="nocache">com..filter.CacheControlPhaseListener</phase-listener></lifecycle>

Я также настроил обработку ошибок в моем файле web.xml:

 <error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/error.jsf</location></error-page>

Я также реализовал ViewExpiredHandler, который расширяет ViewHandlerWrapper

@Override
public UIViewRoot restoreView(FacesContext ctx, String viewId)
{
    UIViewRoot viewRoot = super.restoreView(ctx, viewId);
    try
    {
        if (viewRoot == null)
        {
            viewRoot = super.createView(ctx, viewId);
            ctx.setViewRoot(viewRoot);
        }
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
    return viewRoot;
}

Проблема, которую я до сих пор имею:
1. Когда сеанс истекает на пустой странице (например, на странице поиска) и если на странице запускается какое-либо действие ajax, даже если я выхожу из системы, когда я возвращаюсь на страницу (например, Вход в систему -> Главная страница -> Страница поиска). Я вижу ошибку XML с частичным ответом:

<partial-response><changes><update id="blGridId"><table id="blGridId" style="width:100%;"> <tbody> <tr> <td><div id="blTableId" class="ui-datatable ui-widget ui-datatable-scrollable ui-datatable-resizable"><div id="sublTableId_paginator_top" class="ui-paginator ui-paginator-top ui-widget-header ui-corner-top" role="navigation"><span class="ui-paginator-prev ui-state-default ui-corner-all ui-state-disabled"><span class="ui-icon ui-icon-seek-prev">p</span></span><span class="ui-paginator-next ui-state-default ui-corner-all ui-state-disabled"><span class="ui-icon ui-icon-seek-next">p</span></span></div><div class="ui-widget-header ui-datatable-scrollable-header"><div class="ui-datatable-scrollable-header-box"><table role="grid"><thead id="blTableId_head"><tr role="row"><th id="blTableId:j_idt101" class="ui-state-default ui-resizable-column" role="columnheader" style="width:34px; #width:37px;"><span class="ui-column-title"><span style="word-wrap: break-word;white-space: normal;">Client </span></span></th><th id="blTableId:j_idt104" class="ui-state-default


2. Если я нажму на обновление браузера, он загрузит страницу назад, и я смогу продолжить действия.
Пожалуйста, дайте мне знать, что мне нужно сделать в дополнение к вышеупомянутому, чтобы устранить ошибку частичного ответа. Нужно ли добавлять фильтр сервлетов для аннулирования сеанса?
Я был бы очень признателен за любую помощь и отзывы по этому вопросу, так как это является приоритетным.

1 ответ

У меня возникла та же проблема, когда сеанс истек. Я думал, что было слишком поздно, но, возможно, будет полезно для тех, кто имеет такие проблемы, как я.

Основная причина заключается в том, что Spring Security сохраняет последний запрос перед тем, как перенаправить клиента на аутентификацию. После этого Spring Security попытается выполнить запрос еще раз, когда пользователь заходит на страницу последнего запроса. К сожалению, запрос был ajax/ частичный, и его представление истекло -> частичное содержимое XML было возвращено.

Простой способ избавиться от этой проблемы - удалить поведение Spring Security при сохранении. Класс SavedRequestAwareAuthenticationSuccessHandler используется для обработки такого рода поведения. Настроить как:

<bean id="authenticationFilter"  class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"
        p:authenticationManager-ref="authenticationManager"
        p:authenticationFailureHandler-ref="authenticationFailureHandler"
        p:authenticationSuccessHandler-ref="authenticationSuccessHandler"
        p:usernameParameter="username"
        p:passwordParameter="password">
    </bean>
... 

<bean id="authenticationSuccessHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"
        p:defaultTargetUrl="/"
        p:alwaysUseDefaultTargetUrl="true"/>

Надеюсь, это поможет.

Другие вопросы по тегам