使用Servlet 3.0以编程方式控制登录 [英] Programmatically control login with Servlet 3.0

查看:74
本文介绍了使用Servlet 3.0以编程方式控制登录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经测试了Glassfish 3.0.1中的默认安全性容器,得出的结论是,我不会再花更多的时间了.相反,我想自己控制验证.但是我需要一些指导,以使我步入正轨.

I've tested the default security containers in Glassfish 3.0.1 and come to the conclusion that I won't spend any more time on that. Instead I want to control the verification myself. But I need some guidance to get me on right track.

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

At the moment I have a UserBean that has a login/logout function (see below). And I don't want to use the *j_security_check* built in container, but use core JSF 2.0.

我的问题是

  1. 如果用户未登录(如果访问某些文件夹),我是否需要ServletFilter来重定向流量?
  2. 用户成功登录后如何存储用户密码?

感谢任何帮助或链接到示例,问候克里斯.

Appreciate any help or link to a example, greetings Chris.

PS.对不起,我将两个问题聚在一起

PS. Excuse me for clustering two questions together

@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代替了Realm.在这种情况下,request.login()对您没有用.

When you want to utilize request.login(), then you should really have configured a Realm in the container which represents the user database. But you seem to have replaced the Realm by some AuthenticationFacade. In this case, the request.login() is not useful for you.

您只需要将用户置于会话范围内并在该范围内进行拦截.这是一个启动示例:

You need to just put the user in the session scope and intercept on that. Here's a kickoff example:

@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!)
}

以这种方式进行身份验证时,您肯定需要

When taking authentication in hands like this, then you definitely need a filter to restrict access. When using container managed security you would typically specify it as <url-pattern> of <security-constraint> for this. But without it, you've to take it in your hands. It's good to know that JSF managed beans are keyed by their managed bean name in any scope.

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

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

将上述过滤器映射到所需的网址格式.

Map the above filter on the desired URL-pattern.

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

When you still want to reconsider using container managed authentication, then the following related answers may be useful:

  • Java EE Login Page Problem (and Configuring Realm in Glassfish)
  • Performing user authentication in Java EE / JSF using j_security_check

这篇关于使用Servlet 3.0以编程方式控制登录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆