Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
964 views
in Technique[技术] by (71.8m points)

jsf - Programmatically control login with Servlet 3.0

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.

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.

My questions are;

  1. Do I need a ServletFilter to redirect traffic if the user is not logged in (if accessing certain folders)?
  2. How do I store User Pricipals after the user successfully logged in ?

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

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;
    }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...