This module is targetted to provide a simple solution to authentication and authorization needs of common web applications.

The module IS NOT a service and doesn't pretend to be The solution to all problems in the AAA context, instead it aims to solve the simple and more generic case where the application needs to authenticate the user and show different sections or datas depending on the user profile. In the 0.2.0 version was added the capability to authorize the user upon the operation context and more web-oriented features are under analisys or construction.

Terms and definitions

  • a username is a sequence of alphanumeric characters;
  • a secret is a sequence of bytes (so it's in binary format) representing an information exclusively known to the module and the person or system who has granted access to the application; it can be a pass phrase, a shared cryptographic key, a public-private cryptographic key pair, a fingerprint scan or whatever else can be represented in binary format;
  • the credentials are the username and secret pair which uniquely identify a user into the system.
  • the user is the minimum set of informations needed to authenticate, authorize, audit and manage a person or system who has granted access to the application; tipically those informations are: a display name, the credentials and the status (enabled, disabled, approval pending or online);
  • a group is an aggregating entity capable to contain users;
  • the scope is the datas (or context) onto which one or more operations operate;
  • a permission is a grant to access a resource or operation, eventually within a scope;
  • a role or profile is a figure to which users and groups can be associated; it aggregates a set of permissions;
  • an operation or function is a representation of a functionality providen by the underlying system.

Authentication

The authentication process, or login is credentials based: this means a user needs to provide his own username and secret to be identified.

Whenever a user successfully authenticates into the system all it's roles and permissions are retrived (both those directly associated and those associated to the groups it belongs to). Those informations are returned to the authentication requestor to allow for a role and scope based presentation tier customization.

The authentication process can fail for a number of reasons:

  • the user status is disabled or pending;
  • the credentials doesn't match with the stored ones;
  • the user is already logged into the system (optional).

    On the presentation tier the authentication status can be verified through two custom tags (valid and notValid) or programmatically through the static method net.smartlab.web.auth.User.current() which returns null if no user was authenticated.

    <%@ taglib uri="/WEB-INF/smartweb-auth.tld" prefix="auth"%>
    
    <auth:valid>
      <!-- this piece is sent to client only if the user is currently authenticated -->
    </auth:valid>
    
    <auth:notValid>
      <!-- this piece is sent to client only if the user is not currently authenticated -->
    </auth:notValid>
    import net.smartlab.web.*;
    import net.smartlab.web.auth.*;
    
    public class MyAction extends Action {
            if (User.current() == null) {
                    // this code is executed only if a user has not been authenticated
            } else {
              // this code is executed only if a user is currently authenticated
              System.out.println(User.current().getDisplay());
            }
    }

    The logged in user is automatically bound to the HttpSession by the ActionFilter class.

Authorization

The authorization process has been built to be activable and configurable at configuration time, meaning you don't need to deal with the application security during the development phase.

The previous statement implies you can change your application security constraints whenever you need, adding or removing roles without having to touch your source code nor rebuild your application: all you need is to change the module configuration file and, depending on your application server, restart it.

How it works

The authorization process is role and permission based meaning a user is authorized on a role basis which in turns is only a collection of permissions.

Each permission authorizes a user to perfom a specific action on a specifiable resource, like:

  • listing of sold products;
  • update of sub-categories of the `food` category;
    <%@ taglib uri="/WEB-INF/smartweb-auth.tld" prefix="auth"%>
    
    <auth:valid role="manager">
      <!-- this piece is sent to client only if the user is currently authenticated 
           and belongs to the manager role -->
    </auth:valid>
    
    <auth:valid role="manager" scope="category">
      <!-- this piece is sent to client only if the user is currently authenticated 
           and belongs to the manager role for the object contained into the category
           attribute (page, request or session) -->
    </auth:valid>
    
    <auth:notValid role="manager">
      <!-- this piece is sent to client only if the user is currently authenticated 
           and doesn't belong to the manager role -->
    </auth:notValid>

    However a framework should allow for simplicity without force so if you need to programmatically access to the authorization structure...

    import net.smartlab.web.*;
    import net.smartlab.web.auth.*;
    
    public class MyAction extends Action {
            try {
                    if (User.current().isInRole("manager")) {
                            // this code is executed only if a user is currently authenticated
                            // and belongs to the manager role
                    } else {
                      // this code is executed only if a user is currently authenticated
                      // but doesn't belong to the manager role
                    }
            } catch (NullPointerException npe) {
              // this code is executed if no user was succesfully logged
            }
    }