Жизнь JSF после выхода из системы

Я использую аутентификацию на основе форм.

У меня есть ссылка для выхода, которая выглядит так:

<h:commandLink action="#{loginBean.logout}">
    <h:outputText value="logout" />
</h:commandLink></div>

И соответствующий метод выхода из системы:

public String logout() {
    FacesContext.getCurrentInstance().getExternalContext().invalidateSession();

    return "/view/index?faces-redirect=true"; // Redirect added as per BalusC's suggestion.
}

После нажатия на ссылку выхода я возвращаюсь на главную страницу, но, похоже, без CSS. Когда я нажимаю кнопку для запуска поиска, я получаю следующую ошибку:

javax.faces.application.ViewExpiredException: viewId:/view/index.jsf - View /view/index.jsf could not be restored.

И все же CSS на самом деле находится в /resources, который не должен требовать аутентификации, как я понимаю мой web.xml:

    <security-constraint>
    <web-resource-collection>
        <web-resource-name>fizio</web-resource-name>
        <url-pattern>/*</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
        <role-name>*</role-name>
    </auth-constraint>
</security-constraint>

<security-constraint>
    <web-resource-collection>
        <web-resource-name>Unprotected area</web-resource-name>
        <url-pattern>/resources/*</url-pattern>
    </web-resource-collection>
</security-constraint>

В этом состоянии я, кажется, могу снова войти в систему и увидеть некоторые данные между случайными ошибками просмотра, которые не могут быть восстановлены, но не CSS. Это все немного сломано на самом деле. Мы ценим любые предложения.

ETA: Форма входа:

<form method="POST" action="j_security_check">
    <label for="j_password">Username:</label> <input type="text" name="j_username" />
    <br />
    <label for="j_password">Password:</label> <input type="password" name="j_password" /> <input type="submit" value="Login" />
</form>

person rich    schedule 22.08.2011    source источник


Ответы (1)


Вам нужно перенаправить после недействительности. В противном случае страница будет показана посреди «недействительного» сеанса. Добавьте faces-redirect=true к результату, чтобы активировать перенаправление.

public String logout() {
    FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
    return "/index?faces-redirect=true";
}

Перенаправление заставит веб-браузер запустить новый запрос GET после ответа POST и, в свою очередь, заставит сервер создать новый сеанс. Таким образом, представления будут работать так, как задумано.

Что касается ресурсов CSS, то для них, видимо, все же нужен логин. Ограничение «Незащищенная область», которое у вас есть, не будет работать. Удалите его и измените URL-шаблон вашего основного ограничения безопасности, например, на /app/* или любой другой общий путь защищенной области.

person BalusC    schedule 22.08.2011
comment
Спасибо. Кажется, это имеет небольшое значение - при выходе из системы теперь я вижу страницу входа в систему с CSS. Но если я на самом деле нажму на вход, я вернусь в свое приложение в недействительном состоянии сеанса. Возможно, еще одна проблема с моей формой входа? - person rich; 22.08.2011
comment
Не могли бы вы более подробно описать, что я вернулся в свое приложение из-за проблемы с недействительным состоянием сеанса? Попробуйте взглянуть на проблему с точки зрения разработчика, а не с точки зрения конечного пользователя. Например. есть ли файл cookie сеанса? Есть ли средства изменения идентификатора сеанса? И т.п. - person BalusC; 22.08.2011
comment
О, есть вероятность, что вы просто просматриваете страницу из кеша браузера? Попробуйте создать фильтр, как предложено в следующем ответе: title="Javax Faces Application ViewExpireException View не может быть восстановлен">stackoverflow.com/questions/3642919/ Вы можете проверить, например, с помощью Firebug, просматриваете ли вы страницу из кеша браузера или нет. Другой (неспециалист) тест — нажать Ctrl+F5 после выхода из системы, а затем повторить действие. - person BalusC; 22.08.2011
comment
По-видимому, существует файл cookie сеанса, связанный с корнем контекста, который остается после выхода из системы и снова после входа в систему. Он поддерживает одно и то же значение JSESSIONID, если только я не перейду вручную к корню контекста, когда я получаю новое значение JSESSIONID. - person rich; 22.08.2011
comment
Вы исключили кеш браузера из-за того, что он виноват? Смотрите предыдущий комментарий. Вы обязательно должны получить новый файл cookie сеанса после выхода из системы (но только если страница обслуживается сервером, а не из кеша браузера). - person BalusC; 22.08.2011
comment
Теперь я добавил фильтр. Я ставлю точку останова, в которую попадаю регулярно. Но, похоже, поведение не изменилось. - person rich; 22.08.2011
comment
Это действительно странно. Видите ли вы заголовок Set-Cookie в ответе на перенаправленный запрос? Устанавливает ли фильтр правильный заголовок Cache-Control и другие во всех запросах JSF? Вы очищали кеш браузера перед тестированием? Какой сервлетконтейнер вы используете? Я помню похожие проблемы с файлами cookie сеанса в Resin. - person BalusC; 22.08.2011
comment
Есть 302 POST для index.jsf, за которым следует 200 GET также для index.jsf, у которого есть Set-Cookie со значением JSESSIONID, отличным от значения в Cookie для 302. Я не очищал кеш браузера, Я попробую это сейчас. Я использую JBoss AS7. - person rich; 22.08.2011
comment
Хорошо, эта часть выглядит нормально. Когда вы отправляете форму в index.jsf, в запросе устанавливается тот же Cookie, что и в Set-Cookie перенаправленного ответа GET? - person BalusC; 22.08.2011
comment
Да, он использует значение Set-Cookie при последующей отправке формы входа. Очистка кеша браузера, похоже, ничего не решила. Я вижу, что заголовки, связанные с кешем набора фильтров, возвращаются. - person rich; 22.08.2011
comment
Ладно, эта часть тоже выглядит нормально. Что именно происходит, когда вы после этого отправляете логин? Вы сказали, что я оказываюсь в недействительном состоянии сеанса, но не описали точные симптомы и поведение. Вы вошли в систему или получили ViewExpiredException? Или CSS/JS не работает? И т.п. - person BalusC; 22.08.2011
comment
Таблицы стилей не прикреплены. Кроме того, при попытке выполнить определенные задачи, такие как поиск, я получал ViewExpiredException, хотя похоже, что что-то, сделанное выше, исправило это. Firebug показывает, что таблицы стилей возвращаются как страница формы входа, а не CSS. Кроме того, ссылка на выход из системы, похоже, не имеет никакого эффекта - она ​​не перенаправляется. - person rich; 22.08.2011
comment
О, хорошо, вы действительно должны были прояснить это с самого начала :) Загружены ли ресурсы CSS или нет? Проверьте его с помощью Firebug и проверьте данные ответа. - person BalusC; 22.08.2011
comment
Запросы таблицы стилей получают 200 OK, но данные ответа представляют собой HTML для формы входа, а не CSS. - person rich; 22.08.2011
comment
Да, ваше ограничение безопасности не работает таким образом. Я обновил ответ. - person BalusC; 22.08.2011
comment
Если я удалю раздел незащищенных ресурсов и изменю шаблон URL другого на /jsf-web/*, то при первом доступе к приложению оно не перенаправляется на страницу входа, и я получаю NPE в своем приложении, когда оно пытается получить вошедшего в систему пользователя. - person rich; 22.08.2011
comment
Тогда шаблон URL просто не совпадает. Похоже, вы указали контекстный путь вместо реальной папки в контексте веб-приложения. шаблон URL должен быть контекстно-зависимым. - person BalusC; 22.08.2011
comment
Ах. Добавление трех шаблонов URL-адресов для index.jsp, /view/* и /edit/*, похоже, работает. Спасибо за настойчивость! - person rich; 22.08.2011
comment
Пожалуйста. Пожалуйста, не забудьте отметить принятый ответ, если он помог (больше всего) в решении проблемы. См. также мета. stackexchange.com/questions/5234/. Также рассмотрите возможность просмотра вопросов с непринятыми ответами в истории вопросов stackoverflow.com/users/180416/rich. Если ответа нет, и вы уже решили проблему самостоятельно, вы должны были подробно опубликовать это как ответ. - person BalusC; 22.08.2011