#jsf #logout
#jsf #Выход
Вопрос:
Я не нашел реального решения этой проблемы, даже если она действительно распространена…
У меня есть этот контекст:
- Приложение JSF, запущенное на сервере Glassfish версии v3.1, JDK6. Все на моем персональном компьютере с WinVista (последнее не должно быть важным).
- Используя SSL и базовую аутентификацию (безопасность контейнера)
- Я выполнил свой метод logout () в моем вспомогательном компоненте, сделав сеанс недействительным и отправив перенаправление.
Я не могу заставить контейнер снова отображать окно входа для проверки пользователя и иметь возможность сменить пользователя… И мой пользователь всегда может вернуться, нажав кнопку «НАЗАД» в браузере или просто написав URL-адрес, и продолжить выполнять там действия, когда предполагается, что существующего сеанса быть не должно.
Я получаю имя пользователя, для которого создан мой вспомогательный компонент:
private void setName() {
this.name = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal().getName();
}
И я использую это имя для выполнения операций…
Затем для выхода из системы в моем xhtml есть код:
<h:panelGroup id="logOut">
<h:form>
<h:commandLink id="linkLogOut" action="#{visitor.logout}" value=" Clic here to Log Out" />
</h:form>
</h:panelGroup>
Это вызывает этот метод в моем компоненте::
public void logout() throws IOException {
// FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
this.name = null;
FacesContext fc = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession)fc.getExternalContext().getSession(false);
session.invalidate();
FacesContext.getCurrentInstance().getExternalContext().redirect("https://localhost:8080/");
}
Я объявляю свой резервный компонент с:
@Named(value="visitor")
@SessionScoped
…Также я делал перенаправление из дескриптора развертывания … и это было то же самое.
Если я закрою браузер, сеанс будет потерян, и контейнер снова запросит у меня пользователя / пропуск.
Есть предложения?
Большое спасибо!
Alejandro.
Ответ №1:
Я не могу заставить контейнер снова отображать окно входа для проверки пользователя и иметь возможность сменить пользователя… И мой пользователь всегда может вернуться, нажав кнопку «НАЗАД» в браузере или просто написав URL-адрес, и продолжить выполнять там действия, когда предполагается, что существующего сеанса быть не должно.
Скорее всего, эти страницы отображаются из кэша браузера, а не повторно запрашиваются с сервера. Чтобы остановить это, создайте, Filter
который отображается на интересующий шаблон URL ( *.jsf
может быть?) и выполняет следующую работу в doFilter()
методе:
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Cache-Control", "no-cache,no-store,must-revalidate"); // HTTP 1.1
httpResponse.setHeader("Pragma", "no-cache"); // HTTP 1.0
httpResponse.setDateHeader("Expires", 0); // Proxies.
chain.doFilter(request, response);
Очистите кэш браузера перед тестированием.
Ответ №2:
Большое вам спасибо за все ваши ответы.
Я взял несколько выходных … и не ответил на эту тему.
Я просто хочу поделиться своим решением.
Базовая аутентификация привязана к браузеру, и как только вы выполнили вход в систему, следует закрыть браузер, чтобы завершить выход из системы … что не так элегантно.
Я переключился на аутентификацию ФОРМЫ, создав свою форму и отправив информацию о пользователе сервлету, который проверяет учетные данные пользователя на соответствие моей области, и этот сервлет перенаправляет пользователя либо в приложение, либо на страницу ошибки. Очевидно, что правильная конфигурация, если она ограничивает безопасность в web.xml должно быть выполнено.
Я делюсь своим решением здесь:
Страница входа в систему:
<!-- This is the login page that implement the "Form Base" login -->
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Login Form</title>
</h:head>
<h:body>
<h2>Welcome to the secure messaging service!:</h2>
<form name="loginForm" method="POST" action="j_security_check">
<p><strong>Please type your user name: </strong>
<input type="text" name="j_username" size="25" /></p>
<p><strong>Please type your password: </strong>
<input type="password" size="15" name="j_password" /></p>
<p>
<input type="submit" value="Submit"/>
<input type="reset" value="Reset"/>
</p>
</form>
</h:body>
Мой метод сервлета проверки:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
String username;
String password;
username = request.getParameter("j_username").toString();
password = request.getParameter("j_password").toString();
request.login(username, password);
response.sendRedirect("/SecureMessageWebInterface/");
} catch (Exception e) {
response.sendRedirect("error.xhtml");
}
}
И требуемую часть файла конфигурации….
<security-constraint>
<display-name>Web Interface</display-name>
<web-resource-collection>
<web-resource-name>SSL Pages</web-resource-name>
<description/>
<url-pattern>/</url-pattern>
</web-resource-collection>
<auth-constraint>
<description>All site is restricted</description>
<role-name>user</role-name>
</auth-constraint>
<user-data-constraint>
<description>Secure connection is required</description>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>webapps</realm-name>
<form-login-config>
<form-login-page>/login.xhtml</form-login-page>
<form-error-page>/error.xhtml</form-error-page>
</form-login-config>
</login-config>
Я надеюсь, что это может быть полезно для кого-то еще.
Всего наилучшего,
Alejandro.