以编程方式使用Servlet 3.0控制登录

时间:2011-05-31 14:58:43

标签: jsf servlets servlet-filters

我已经测试了Glassfish 3.0.1中的默认安全容器,并得出结论,我不会再花费更多时间。相反,我想自己控制验证。但我需要一些指导才能让我走上正轨。

目前我有一个具有登录/注销功能的UserBean(见下文)。我不想使用* j_security_check *内置容器,但使用核心JSF 2.0。

我的问题是;

  1. 如果用户未登录(如果访问某些文件夹),是否需要ServletFilter来重定向流量?
  2. 用户成功登录后如何存储用户权限?
  3. 感谢任何帮助或指向示例的链接,问候Chris。

    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 个答案:

答案 0 :(得分:9)

如果要使用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!)
}

在这样的手中进行身份验证时,您肯定需要filter来限制访问权限。使用容器托管安全性时,您通常会将其指定为<url-pattern> <security-constraint>。但没有它,你就要把它拿在手里。很高兴知道JSF托管bean在任何范围内都受其托管bean名称的限制。

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

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

将上述过滤器映射到所需的URL模式。


如果您仍想重新考虑使用容器管理的身份验证,则以下相关答案可能会有用:

答案 1 :(得分:0)

如果您使用的是JDBC领域安全性,请注意。在Glassfish管理控制台中配置领域的字段中有一些固定/预期的单词。

JAAS上下文字段中,您必须输入: jdbcRealm 。此关键字使安全容器使用预期的JDBC领域。如果您输入其他内容,则无效。

这是一个很好的例子,由Gordan Jugo完成; Netbeans/Glassfish JDBC Security Realm