Вход в сеанс HTTP JSF
Я пытаюсь создать форму входа в веб-приложение.
на странице JSP я могу использовать
<%
String name = request.getParameter( "username" );
session.setAttribute( "theName", name );
%>
но теперь я использую JSF/Facelets для веб-приложения
Я не знаю, как создать сеанс в JSF Backing bean для клиента и проверить, зарегистрирован ли пользователь или нет, поэтому он будет перенаправлен на страницу входа.
кто может помочь мне дать мне ссылку на эту проблему?
спасибо перед
Теперь у меня мало проблем с отображением в web.xml
код отключен класса Фильтр
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.config = filterConfig;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
LoginController controller = (LoginController) req.getSession()
.getAttribute("loginController");
if (controller == null || !controller.isLoggedIn()) {
res.sendRedirect("../admin/login.xhtml");
} else {
chain.doFilter(request, response);
}
}
и в web.xml
Я сопоставляю тег <fitler>
<filter>
<filter-name>userLoginFilter</filter-name>
<filter-class>com.mcgraw.controller.UserLoginFilter</filter-class>
<init-param>
<param-name>loginPage</param-name>
<param-value>/login.xhtml</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>userLoginFilter</filter-name>
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
У меня есть один администратор папки в веб-проекте, и я проверяю, не был ли пользователь зарегистрирован с правами администратора, чтобы не получить доступ к странице (я могу выполнить проверку разрешения), но когда я использую фильтр, браузер не понимает URL-адрес??
no StackTrace показать, когда браузер не понимает URL
Ошибка, отображаемая в Firefox
The page isn't redirecting properly
на IE это загрузка... загрузка... нон-стоп
теперь я меняю условие, которое проверяет, будет ли req.getPathInfo.startsWith( "/login.xhtml" ) цепочка
У меня есть идея 2, но ответ 500 HTTP STATUS
if (controller == null || !controller.isLoggedIn()) {
res.sendRedirect("../admin/login.xhtml");
if(req.getPathInfo().startsWith("/login.xhtml")){
chain.doFilter(request, response);
}
} else {
chain.doFilter(request, response);
}
===============
if (controller == null || !controller.isLoggedIn()) {
if (!req.getPathInfo().startsWith("/login.xhtml")) {
res.sendRedirect("../admin/login.xhtml");
} else {
chain.doFilter(request, response);
}
} else {
chain.doFilter(request, response);
}
======================
обновление Класс loginController
package com.mcgraw.controller;
import com.DAO.UserBean;
import com.entity.IUser;
import java.io.Serializable;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
/**
* @author Kency
*/
@ManagedBean
@SessionScoped
public class LoginController implements Serializable {
@EJB
private UserBean userBean;
private IUser user;
private boolean admin;
private boolean mod;
private PasswordService md5;
/** Creates a new instance of LoginController */
public LoginController() {
user = new IUser();
md5 = new PasswordService();
}
// getter / setter
public boolean isMod() {
return mod;
}
public void setMod(boolean mod) {
this.mod = mod;
}
public IUser getUser() {
return user;
}
public void setUser(IUser user) {
this.user = user;
}
public boolean isAdmin() {
return admin;
}
public void setAdmin(boolean admin) {
this.admin = admin;
}
public String cplogin() {
String md5Password = md5.md5Password(user.getPassword());
if (userBean.userLogin(user.getUsername(), md5Password) != null) {
if (user.getUsername() != null || md5Password != null) {
user = userBean.userLogin(user.getUsername(), md5Password);
if (user.getGroups().getAdmin() != null) {
setAdmin(user.getGroups().getAdmin());
}
if (user.getGroups().getMods() != null) {
setMod(user.getGroups().getMods());
}
if (isAdmin() == true || isMod() == true) {
return "home";
} else {
return "login";
}
} else {
return "login";
}
} else {
return "login";
}
}
public String logout() {
user = null;
return "login";
}
public boolean isLoggedIn() {
return user != null;
}
}
У меня есть новая проблема, если рендеринг JSF taglib с методом loggedIn, на индексной странице (не в папке администратора) пользователь не может войти в систему, может видеть, что я визуализирую пример, < == this like if user does not login user can Видите ли, почему он может это увидеть?
Ответы
Ответ 1
Вы можете в JSF получить/установить атрибуты сеанса HTTP через ExternalContext#getSessionMap()
, который в основном является оберткой вокруг HttpSession#get/setAttribute()
.
@ManagedBean
@RequestScoped
public class LoginController {
private String username;
private String password;
@EJB
private UserService userService;
public String login() {
User user = userService.find(username, password);
FacesContext context = FacesContext.getCurrentInstance();
if (user == null) {
context.addMessage(null, new FacesMessage("Unknown login, try again"));
username = null;
password = null;
return null;
} else {
context.getExternalContext().getSessionMap().put("user", user);
return "userhome?faces-redirect=true";
}
}
public String logout() {
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
return "index?faces-redirect=true";
}
// ...
}
На странице Facelets просто привяжите поля ввода username
и password
к этому bean и выполните соответственно действие login()
.
<h:form>
<h:inputText value="#{loginController.username}" />
<h:inputSecret value="#{loginController.password}" />
<h:commandButton value="login" action="#{loginController.login}" />
</h:form>
Атрибуты сеанса напрямую доступны в EL. Атрибут сеанса с именем user
находится в EL, доступном как #{user}
. При тестировании, если пользователь зарегистрирован в некотором атрибуте rendered
, просто проверьте, не является ли он empty
или нет.
<h:panelGroup rendered="#{not empty user}">
<p>Welcome, #{user.fullName}</p>
<h:form>
<h:commandButton value="logout" action="#{loginController.logout}" />
</h:form>
</h:panelGroup>
Действие выхода из системы в основном просто разбивает сеанс.
Что касается проверки входящего запроса, если пользователь вошел в систему или нет, просто создайте Filter
, который делает примерно следующее в doFilter()
метод:
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
String loginURI = request.getContextPath() + "/login.xhtml";
boolean loggedIn = session != null && session.getAttribute("user") != null;
boolean loginRequest = request.getRequestURI().equals(loginURI);
boolean resourceRequest = request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER);
if (loggedIn || loginRequest || resourceRequest) {
chain.doFilter(request, response);
} else {
response.sendRedirect(loginURI);
}
}
Сопоставьте его на url-pattern
, охватывающем ограниченные страницы, например. /secured/*
, /app/*
и т.д.
См. также:
Ответ 2
Попробуйте это в своей поддержке bean при получении запроса (например, в методе действий):
HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
HttpSession session = request.getSession();
Затем вы можете работать с объектами запроса и сеанса так же, как и с JSP, настройкой атрибутов и т.д.
Вы также можете взглянуть на мой вопрос о проверке сеанса клиента в фильтре сервлета. Вы можете написать аналогичный фильтр, чтобы проверить вход пользователя в свой HttpSession, а затем сделать перенаправление (или RequestDispatch, как я делал), на вашу страницу входа в систему, если это необходимо.