用Servlet 3.0编程控制登录



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

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

我的问题是:;

  1. 如果用户没有登录(如果访问某些文件夹),我是否需要Servlet Filter来重定向流量
  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;
    }

当您想要使用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!)
}

当像这样进行身份验证时,您肯定需要一个过滤器来限制访问。当使用容器管理的安全性时,通常会为此将其指定为<security-constraint><url-pattern>。但如果没有它,你必须把它掌握在自己手中。很高兴知道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模式。


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

  • Java EE登录页面问题(以及在Glassfish中配置Realm)
  • 使用j_security_check在Java EE/JSF中执行用户身份验证

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

JAAS上下文:文件中,您必须键入:jdbcRealm。这个关键字使安全容器使用预期的JDBC领域。如果你键入其他内容,它将不起作用。

这是一个很好的例子,由戈尔丹·朱戈完成;Netbeans/Glassfish JDBC安全领域

相关内容

  • 没有找到相关文章

最新更新