Configuring security for a Liberty JVM server with the Java EE security API 1.0

Java EE 8 introduces a portable, flexible, and standardized security model with the Java EE security API 1.0. A Liberty JVM server can be configured to respect the new security configuration through the inclusion of the Liberty appSecurity-3.0 feature.

The Java EE security API 1.0 specification covers three principles:
  1. Authentication mechanism: provided by the HttpAuthenticationMechanism interface for the servlet container
  2. Identity store: an attempt to standardize the JAAS LoginModule
  3. Security context: an access point for programmatic security

Authentication mechanism

An authentication mechanism is a way that is used to obtain a username and password from the user to be processed later by the Java Security API. There are two standard options for authentication, both take advantage of the annotations that are introduced by the Java EE security 1.0 API.

HTTP basic authentication
Basic authentication displays the browser's native login dialog before the user can access the protected resource.
@BasicAuthenticationMechanismDefinition(realmName="user-realm") 
@WebServlet("/home") @DeclareRoles({"user"}) 
@ServletSecurity(@HttpConstraint(rolesAllowed = "user")) 
public class HomeServlet extends HttpServlet { 
    ... 
}
Form-based authentication
You can use form-based authentication to replace the browser’s built-in dialog with your own custom HTML form. You can create an application config class with annotations as follows:
@FormAuthenticationMechanismDefinition(
    loginToContinue = @LoginToContinue(
        loginPage = "/login",
        errorPage = "/error"
    ) 
)
@ApplicationScoped
public class ApplicationConfig {
    ...
}

Identity store

A component acts as a DAO (Data Access Object) for accessing user information, including their usernames, passwords, and associated roles. A number of identity store types are introduced by the Java EE security API 1.0, including:
Database identity store
A database identity store is used to retrieve user information from a relation database.
@DatabaseIdentityStoreDefinition(
dataSourceLookup = "jdbc/sec",
    callerQuery = "#{'select password from USR where USERNAME = ?'}",
    groupsQuery = "#{'select ugroup from USR where USERNAME = ?'}",
    hashAlgorithm = Pbkdf2PasswordHash.class,
    priorityExpression = "#{100}",
    hashAlgorithmParameters = {
        "Pbkdf2PasswordHash.Iterations=3072",
        "Pbkdf2PasswordHash.Algorithm=PBKDF2WithHmacSHA512",
        "Pbkdf2PasswordHash.SaltSizeBytes=64"
    }
)
Lightweight Directory Access Protocol (LDAP) identity store

LDAP is a common way of organizing a user's access to different systems across a single organization. LDAP realizes the idea of Single-Sign On, where a user has a single username and password, and then uses it across all different systems that are used to perform the everyday business of a specific organization.

@WebServlet("/home")
@ServletSecurity(@HttpConstraint(rolesAllowed = "user"))
@LdapIdentityStoreDefinition(
    url = "ldap://localhost:33389/",
    callerBaseDn = "ou=user,dc=jsr375,dc=net", 
    groupSearchBase = "ou=group,dc=jsr375,dc=net"
)
public class HomeServlet extends HttpServlet{ 
    ...
}

URL: The URL of the LDAP server to use for authentication.

callerBaseDn: Base distinguished name for callers in the LDAP store.

groupSearchBase: Search base for looking up groups.

Custom identity store

In addition to the built-in identity stores found in Java EE security API 1.0, a user can implement their own identity store and control exactly where to obtain user information. This can be achieved by creating a custom identity store class, then creating an HTTP authentication mechanism associated with this custom identity store.

Security context

The security context object is used to programmatically check a user's authority to access a specific resource. This is useful when you need to perform custom behavior. In this example, the user is forwarded to another page only if they have access to it:

@WebServlet("/home")
public class HomeServlet extends HttpServlet {
    @Inject
    private SecurityContext securityContext;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
        if (securityContext.hasAccessToWebResource("/anotherServlet", "GET")) {
            req.getRequestDispatcher("/anotherServlet").forward(req, res);
        } else {
            req.getRequestDispatcher("/logout").forward(req, res);
        }
    }
}

For more information about the Java EE 8 security API, see Java EE Security API in the Liberty Knowledge Centre.