Some content

AuthRequest

AuthRequest allows to attach the appropriate authentication information to incoming request. It is optional, but often a must if you have user authentication for part or all of your Web application.

AuthRequest Setup

The way to implement a custom AuthService is to just Guice bind AuthService in the WebApplication Module, like.

package com.example.snow;
import com.google.inject.AbstractModule;

public class MyAppConfig extends AbstractModule {
    @Override
    protected void configure() {
      bind(AuthRequest.class).to(MyAppAuthRequest.class);
    }
}  

AuthRequest Implementation

Then, implement the AuthRequest inteface as:

public class MyAppAuthRequest implements AuthRequest {
  
    public AuthToken authRequest(RequestContext rc){
      // get the User from session or cookie info
      User user = getUserFromRequest(rc);
      
      // validate user with this request 
      if (isValidRequestForUser(rc,user)){
          // Note: User is an Application Class, Snow does not have any User class
          // Note: AuthToken is a typed Snow class. Its main purpose is to set the Application
          // User object
          AuthToken<User> authToken = new AuthToken<User>();
          authToken.setUser(user);
          return authToken;
      }else{
          return null; // meaning, no user for this request
      }
    }
}       

AuthRequest Stateless Example

Here is an example of a stateless (i.e., no servlet session) based authentication scheme.

So, in this case the @WebActionHandler Login will create a cookie userToken as a sha1 hash from username+password, and put it in the cookie, and the AuthRequest will just check that the userToken match

public class MyAppAuthRequest implements AuthRequest {

    // Note: UserDao and User class are application specific, 
    //       Snow does not have to have any knowledge of user to 
    //       enable authentication
    @Inject
    private UserDao userDao; 
    
    @Override
    public AuthToken authRequest(RequestContext rc) {
        // Note: this is not the login logic, the login logic would be 
        //        @WebActionHandler that would generate the appropriate 
        
        // Note: this is a simple stateless authentication scheme. 
        //       Security is medium-low, however, with little bit more logic
        //       it can be as secure as statefull login while keeping it's scalability attributes
        
        // First, we get userId and userToken from cookie
        String userIdStr = rc.getCookie("userId");
        String userToken = rc.getCookie("userToken");
        
        if (userIdStr != null && userToken != null){
            // get the User from the DAO
            Long userId = ObjectUtil.getValue(userIdStr, Long.class, null);
            User user = userDao.get(userId);
            
            // Build the expectedUserToken from the user info 
            // For this example, simplistic userToken (sha1(username,password))
            String expectedUserToken = Hashing.sha1().hashString(user.getUsername() + user.getPassword()).toString();
            
            if (Objects.equal(expectedUserToken, userToken)){
                // if valid, then, we create the AuthTocken with our User object
                AuthToken<User> authToken = new AuthToken<User>();
                authToken.setUser(user);
                return authToken;
                
            }else{
                // otherwise, we could throw an exception, or just return null
                // In this example (and snowStarter, we just return null)
                return null;
            }
        }else{
            return null;
        }
    }
}