Question

I have a JSF web application that uses cookies for automatic authentication without prompting for username & password. It uses a cookie with username and a random UUID, and uses a WebFilter for redirection.

When there are no cookies on the client side, the authentication is done through HttpServletRequest #login(String username, String password). Behind the scenes, this approach uses JAAS authentication, and uses a LDAP server behind.

My problem comes when my application recognizes the user through the cookies holding the userid and the UUID. In this situation,

  1. the application doesn't know the password, so the method HttpServletRequest #login(String username, String password) cannot be used.
  2. Should I ask the password to the LDAP server through JNDI? This doesn't seem to be possible at a first glance
  3. Alternatively, I could store the password in my db. But this would mean duplication of information, and I don't like it.
  4. I have seen around people simply setting the attribute "role" to the session, but this doesn't seem to be equivalent to a JAAS login. With "equivalent" I mean being able to use isUserInRole() and getUserPrincipal() methods.

So, the question is: how am I supposed to log in the user in this case? I hope that the question is clearer now.

EDIT

In order to let the code speak, I add a simplified version of the Managed Bean:

@ManagedBean
@SessionScoped 
public class loginBean() {
    private String username = null;
    private String password = null;
    private UUID uuid = null;
    private boolean rememberMe = false;

    public void doLogin() {
        checkCookies();   // this method sets the property values after checking if 
                          // username & uuid match the ones saved previously
        if (username != null && uuid != null && rememberMe) {
            // authenticate automatically. Here I don't know how to proceed, because 
            // I don't have the password, unless I have saved it in the application's db,
            // duplicating it because it's already in LDAP server.
        } else {
            httpServletRequest.login(username, password);  // this uses LDAP behind JAAS
            createCookies();  // this method also saves username & uuid in the app's db
        }
    }
Était-ce utile?

La solution

To do an actual container login in a custom way (in your case via an cookie and UUID instead of the password), you need to create your own login module.

The dedicated API in Java EE for this is JASPI/JASPIC (people can never quite agree on the name, complicating eg google queries).

A login module is in full control and does not have to authenticate with the ldap server (if your app can locally verify with 100% certainty that the cookie is valid). You probably do have to authorize the user (ask the ldap server for the roles/groups the user has).

As an alternative to JASPI/JASPIC you can also look at the proprietary login module mechanism that your server is using.

Autres conseils

Using an LDAP entry for this case is equivalent to requesting that the directory server authenticate a connection using information provided by the application. In terms of LDAP, authenticate means that an existing LDAP session, that is, a connection to a directory server, has had its authentication state changed by a successful BIND request.

The web application should request appropriate information from the user to be authenticated and present this information to the directory server as a BIND request. The information required varies according to the authentication method used by the web application (LDAP client):

  • A simple BIND request requires a distinguished name and a password. This distinguished name and password should be transmitted to the directory server as a simple BIND request over a secure connection.
  • A SASL BIND request using a predefined SASL mechanism. The mechanisms vary per server and range from GSSAPI to PLAIN.

Upon receipt of the BIND request, the directory server will immediately change the authentication state of the connection to anonymous and process the BIND request. If the request can be successfully processed, the directory server responds to the LDAP with a BIND response including an integer result code of zero (0). This indicates that the distinguished name or username was able to successfully authenticate.

The web application should use some mechanism to maintain an authentication state and issue a BIND request to the directory server when the authentication state changes. This could be a session timeout, or some other mechanism. The method that is chosen should not be changeable by the user.

In summary, use the directory server to check authentication credentials and use the session framework to manage authentication state.

Edit:

Seems this was a controversial answer.

  • Using cookies does not handle the case of the browser having cookies disabled, and cookies are not necessary to maintain an authentication state when using sessions.
  • The session does not need the password, nor should it store any sensitive information like passwords in memory or sessions. The application should request the password when the authentication state expires (if ever) or the session expires (if ever).
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top