开发者

Programmatically control login with Servlet 3.0

开发者 https://www.devze.com 2023-03-09 23:33 出处:网络
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

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 authen开发者_开发百科ticateUser;
...

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;
    }


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


Be aware if you are if you are using JDBC realm security. There are some fixed/expected words in the fields where you configure the realm in the Glassfish admin console.

In the JAAS Context: filed, you have to type: jdbcRealm. This keyword makes the security container use the expected JDBC realm. If you type something else, it won't work.

Here is good example, done by Gordan Jugo; Netbeans/Glassfish JDBC Security Realm

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号