Вход в JSF HTTP сессию - PullRequest
       2

Вход в JSF HTTP сессию

20 голосов
/ 01 октября 2010

Я пытаюсь создать форму входа в веб-приложение.на странице JSP я могу использовать

<%
   String name = request.getParameter( "username" );
   session.setAttribute( "theName", name );
%>

, но сейчас я использую JSF / Facelets для веб-приложения. Я не знаю, как создать сеанс в компоненте JSF Backing для клиента и проверить, вошел ли пользователь в систему или нет.поэтому он будет перенаправлен на страницу входа.Кто может помочь мне дать ссылку на учебник по этой проблеме?спасибо раньше

Теперь у меня есть небольшая проблема с отображением в коде web.xml, отсекаемом из класса Filter

@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>

У меня есть одна папка admin в веб-проекте, и я проверяю, не вошел ли пользователь с правами администратора, чтобы не заходить на страницу (я могу выполнить проверку разрешений), но когда я использую фильтр, браузер не понимаетURL ??нет StackTrace показывать, когда браузер не понимает URL

Ошибка отображается в Firefox

The page isn't redirecting properly

в IE it loading ... loading... нон-стоп

теперь я изменяю условие, которое проверяет, если req.getPathInfo.startsWith ("/ login.xhtml") это сделает цепочку

У меня есть 2 идеи, но это ответ 500 HTTPСОСТОЯНИЕ

 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);
}

====================== update Class 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, на странице индекса (не в папке администратора) пользователь не авторизуется, может увидеть пример рендеринга, <== это похоже на то, что если пользователь не входит в систему, пользователь не может видеть, но почему он может это видеть? </p>

Ответы [ 2 ]

47 голосов
/ 01 октября 2010

Вы можете в JSF получить / установить атрибуты сеанса HTTP через ExternalContext#getSessionMap(), который в основном является оберткой для HttpSession#get/setAttribute().

@Named
@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 с этим компонентом и соответственно вызовите действие 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/* и т. Д.

См. Также:

1 голос
/ 01 октября 2010

Попробуйте это в своем компоненте поддержки при получении запроса (как в методе действия):

HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
HttpSession session = request.getSession();

Затем вы можете работать с объектами запроса и сеанса так же, как вы привыкли с JSP, устанавливаяатрибуты и т. д.

Возможно, вы также захотите взглянуть на мой связанный вопрос о проверке сеанса клиента в фильтре сервлета .Вы можете написать аналогичный Фильтр для проверки входа пользователя в их HttpSession, а затем, при необходимости, выполнить перенаправление (или RequestDispatch, как я это сделал) на вашу страницу входа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...