Программно контролировать вход в систему с Servlet 3.0 - PullRequest
6 голосов
/ 31 мая 2011

Я протестировал контейнеры безопасности по умолчанию в Glassfish 3.0.1 и пришел к выводу, что больше не буду тратить на это больше времени.Вместо этого я хочу контролировать проверку самостоятельно.Но мне нужно некоторое руководство, чтобы вывести меня на правильный путь.

На данный момент у меня есть UserBean, который имеет функцию входа / выхода из системы (см. Ниже).И я не хочу использовать встроенный контейнер * j_security_check *, но использую ядро ​​JSF 2.0.

Мои вопросы:

  1. Нужен ли ServletFilter для перенаправления трафика, еслипользователь не вошел в систему (при доступе к определенным папкам)?
  2. Как сохранить пользовательские цены после того, как пользователь успешно вошел в систему?

Оцените любую помощь или ссылку на пример,привет Крис.

PS.Извините за объединение двух вопросов

@ManagedBean
@SessionScoped
public class UserBean {

private AuthenticateUser authenticateUser;
...

public String login() {
    FacesContext context = FacesContext.getCurrentInstance();
    HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();

    JsfUtil.log("Username : " +authenticateUser.getUserName());
    JsfUtil.log("Password : " +authenticateUser.getPassword());
    AuthenticateUser authRequest = authenticationFacade.find(authenticateUser);
    try {
        if(!authRequest.equals(authenticateUser))
            return "/loginError";

        request.login(authenticateUser.getUserName(), authenticateUser.getPassword());
        return "";
    } catch(ServletException e){
       JsfUtil.addErrorMessage(e, "Incorrect username or password, please try again.");
       return "/loginError";
    }

...
public String logOut() {
    String result = "/index?faces-redirect=true";
    FacesContext context = FacesContext.getCurrentInstance();
    HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();

    try {
        request.logout();
    } catch (ServletException e) {
        JsfUtil.log("Failed to logout user!" +e.getRootCause().toString());
        result = "/loginError?faces-redirect=true";
    }
    return result;
    }

Ответы [ 2 ]

9 голосов
/ 31 мая 2011

Если вы хотите использовать request.login(), тогда вы действительно должны настроить Realm в контейнере, который представляет пользовательскую базу данных.Но вы, кажется, заменили Царство каким-то AuthenticationFacade.В этом случае request.login() вам не нужен.

Вам нужно просто поместить пользователя в область сеанса и перехватить его.Вот начальный пример:

@ManagedBean
@SessionScoped
public class UserManager {

    @EJB
    private UserService userService;
    private String username;
    private String password;
    private User current;

    public String login() {
        current = userService.find(username, password);

        if (current == null) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Unknown login, try again"));
            return null;
        } else {
            return "userhome?faces-redirect=true";
        }
    }

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

    public boolean isLoggedIn() {
        return current != null;
    }

    // Getters/setters (but do NOT provide a setter for current!)
}

Когда вы берете аутентификацию в руки, как это, вам определенно необходим фильтр для ограничения доступа.При использовании безопасности, управляемой контейнером, для этого обычно указывается значение <url-pattern> из <security-constraint>.Но без этого вы должны взять это в свои руки.Полезно знать, что управляемые bean-компоненты JSF вводятся с помощью имени управляемого bean-компонента в любой области.

UserManager userManager = ((HttpServletRequest) request).getSession().getAttribute("userManager");

if (userManager == null || !userManager.isLoggedIn()) {
    ((HttpServletResponse) response).sendRedirect("login.xhtml");
} else {
    chain.doFilter(request, response);
}

Сопоставьте вышеуказанный фильтр с нужным URL-шаблоном.


Когда выЕсли вы все еще хотите пересмотреть использование аутентификации, управляемой контейнером, тогда могут быть полезны следующие связанные ответы:

0 голосов
/ 01 июня 2011

Будьте внимательны, если вы используете безопасность области JDBC. В полях, где вы настраиваете область в консоли администратора Glassfish, есть несколько фиксированных / ожидаемых слов.

В контексте JAAS: в поле необходимо ввести: jdbcRealm . Это ключевое слово заставляет контейнер безопасности использовать ожидаемую область JDBC. Если вы введете что-то еще, это не сработает.

Вот хороший пример, сделанный Горданом Джуго; Netbeans / Glassfish JDBC Security Realm

...