Проверьте, существует ли сессия JSF
У меня есть страница входа, где у меня есть бин User для аутентификации имени пользователя и пароля для человека. Этот боб является сессионной областью действия. Если кто-то пишет URL-адрес и пытается перейти на страницу входа, как я могу проверить это и перенаправить его на страницу входа?
С другой стороны. Предположим, я вошел в систему и работал, и внезапно я ухожу на некоторое время, и мой сеанс истекает. Когда я возвращаюсь и пытаюсь взаимодействовать с формой, она отправляет мне сообщение об окончании сеанса. Как я могу перенаправить снова на форму входа в систему, когда это происходит?
Заранее спасибо. Надеюсь, я объясню.
Мохарра 2.1.4, Tomcat 7, Томагавк 1.1.11
2 ответа
Если кто-то пишет URL-адрес и пытается перейти на страницу входа, как я могу проверить это и перенаправить его на страницу входа?
Вы, кажется, используете доморощенную аутентификацию. В этом случае вам нужно внедрить фильтр сервлетов. JSF сохраняет управляемые bean-объекты в качестве атрибутов HttpSession
так что вы можете просто проверить это в doFilter()
метод:
HttpServletRequest req = (HttpServletRequest) request;
UserManager userManager = (UserManager) req.getSession().getAttribute("userManager");
if (userManager != null && userManager.isLoggedIn()) {
chain.doFilter(request, response);
} else {
HttpServletResponse res = (HttpServletResponse) response;
res.sendRedirect(req.getContextPath() + "/login.xhtml");
}
Установите этот фильтр на шаблон URL, охватывающий защищенные страницы, например /app/*
,
Когда я возвращаюсь и пытаюсь взаимодействовать с формой, она отправляет мне сообщение об окончании сеанса. Как я могу перенаправить снова в форму входа, когда это происходит?
Я так понимаю, что это касается запросов Ajax? Для обычных запросов вы могли бы использовать <error-page>
в web.xml
, Если установить метод сохранения состояния для клиента в web.xml
следующее
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
это не вариант, то вам нужно реализовать кастом ExceptionHandler
:
public class ViewExpiredExceptionHandler extends ExceptionHandlerWrapper {
private ExceptionHandler wrapped;
public ViewExpiredExceptionHandler(ExceptionHandler wrapped) {
this.wrapped = wrapped;
}
@Override
public void handle() throws FacesException {
FacesContext facesContext = FacesContext.getCurrentInstance();
for (Iterator<ExceptionQueuedEvent> iter = getUnhandledExceptionQueuedEvents().iterator(); iter.hasNext();) {
Throwable exception = iter.next().getContext().getException();
if (exception instanceof ViewExpiredException) {
facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext, null, "viewexpired");
facesContext.renderResponse();
iter.remove();
}
}
getWrapped().handle();
}
@Override
public ExceptionHandler getWrapped() {
return wrapped;
}
}
(обратите внимание, что этот конкретный пример переходит к viewexpired
так что он ожидает /viewexpired.xhtml
как страница ошибки)
Выше должно быть испечено следующим ExceptionHandlerFactory
реализация:
public class ViewExpiredExceptionHandlerFactory extends ExceptionHandlerFactory {
private ExceptionHandlerFactory parent;
public ViewExpiredExceptionHandlerFactory(ExceptionHandlerFactory parent) {
this.parent = parent;
}
@Override
public ExceptionHandler getExceptionHandler() {
return new ViewExpiredExceptionHandler(parent.getExceptionHandler());
}
}
который в свою очередь должен быть зарегистрирован в faces-config.xml
следующее:
<factory>
<exception-handler-factory>com.example.ViewExpiredExceptionHandlerFactory</exception-handler-factory>
</factory>
Если вы внедряете свою собственную систему, вы можете добавить атрибут для пользователя, называемый сеанс или что-то еще. Этот атрибут может быть логическим, поэтому при каждом запуске сеанса вы можете установить для этого атрибута значение true. Напишите метод, называемый правами доступа, например:
public void permission() throws IOException {
if(userStatelessBean.getSession() == false) {
System.out.println("*** The user has no permission to visit this page. *** ");
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
context.redirect("login.xhtml");
} else {
System.out.println("*** The session is still active. User is logged in. *** ");
}
}
На каждой странице jsf (для этого примера), для которой вы хотите установить ограничения, вы можете добавить следующий код в самом начале вашей страницы:
<f:metadata>
<f:event type="preRenderView" listener="#{sesija.permission()}"/>
</f:metadata>
Для этого перед вызовом страницы вызовите JSF ManagedBean с именем объекта sesija и проверьте, выполнены ли правила, созданные вами в указанном методе, или нет.
Я надеюсь, что вы найдете это полезным,
Спасибо.