HomeJ2EE JAAS Authorization and AuthenicationJ2EE Security Model -JAAS

J2EE Security Model -JAAS

What is JAAS?

The Java Authentication and Authorization Service (JAAS) implements a Java version of the standard Pluggable Authentication Module (PAM) framework. JAAS simplifies Java security development by putting an abstraction layer between the application and the underlying authentication mechanisms, thereby enabling applications to be independent from the authentication mechanism.

 

 

 

New or updated authentication mechanisms can be plugged in without requiring modifications to the application. Applications initiate authentication by instantiating a LoginContext object, which in turn references a configuration that determines the authentication mechanisms or LoginModules to be used in performing the authentication. If authentication is successful, the subject is updated by a LoginModule with relevant principals and credentials.

Classes and interfaces

LoginModule (javax.security.auth.spi.LoginModule)

Login modules are written by implementing this interface; they contain the actual code for authentication. It can use various mechanisms to authenticate user credentials. The code could retrieve a password from a database and compare it to the password supplied to the module. It could also use a flat file, LDAP or any other means of storing user information for that purpose. Generally, in enterprise networks all authentication credentials are stored in one place, which might be accessed through LDAP.

LoginContext (javax.security.auth.login.LoginContext)

The login context is the core of the JAAS framework which kicks off the authentication process by creating a Subject. As the authentication process proceeds, the subject is populated with various principals and credentials for further processing.

Subject (javax.security.auth.Subject)

A subject represents a single user, entity or system –in other words, a client– requesting authentication.

Principal (java.security.Principal)

A principal represents the face of a subject. It encapsulates features or properties of a subject. A subject can contain multiple principals.

Credentials

Credentials are nothing but pieces of information regarding the subject in consideration. They might be account numbers, passwords, certificates etc. As the credential represents some important information, the further interfaces might be useful for creating a proper and secure credential – javax.security.auth.Destroyable and javax.security.auth.Refreshable. Suppose that after the successful authentication of the user you populate the subject with a secret ID (in the form of a credential) with which the subject can execute some critical services, but the credential should be removed after a specific time. In that case, one might want to implement the Destroyable interface. Refreshable might be useful if a credential has only a limited timespan in which it is valid.

Web Application URL-Based Authorization

In the J2EE security model, Web resources to be secured are identified by their URL patterns. This is specified in the web.xml file of the Web application. For example, the following excerpt is from the configuration to protect resources under the URL pattern “/resource” of an application.

<web-resource-collection>
    <web-resource-name>resource access</web-resource-name>
    <url-pattern>/resource</url-pattern>
  </web-resource-collection>

This is part of a security constraint in web.xml that also specifies the J2EE logical role that is allowed to access the resource. J2EE logical roles, discussed in the J2EE specification, include developers (application component providers), assemblers, deployers, and system administrators.

For example, assume the J2EE role sr_developers is declared in the web.xml file. The security constraint to allow this role to access the resource would look like this:

<security-constraint>
    <web-resource-collection>
      <web-resource-name>resource access</web-resource-name>
      <url-pattern>/resource</url-pattern>
    </web-resource-collection>
    <!-- authorization -->
    <auth-constraint>
      <role-name>sr_developers</role-name>
    </auth-constraint>
 </security-constraint>

The Java Authorization Contract for Containers (JACC) specification (JSR-115) defines new java.security.Permission classes to satisfy the Java EE 5 authorization model. JACC enables authorization decisions based on these permission classes.

This is a sample to use JAAS authentication with a windows active directory server. I use a Sun Java System Application Server, so the steps with other servers could be different.

Step 1: Defining LDAP realm

In this example you must define a LDAP realm named «ads-realm» with the following parameters:

Realm class:

com.sun.enterprise.security.auth.realm.ldap.LDAPReam

Properties:

directory            = ldap://ads.host.name:389
base-dn              = DC=ads,DC=domain,DC=com
search-bind-dn       = user
search-bind-password = password
search-filter        = (&(objectClass=user)(sAMAccountName=%s))
group-search-filter  = (&(objectClass=group)(member=%d))
jaas-context         = ldapRealm

You must change directory, base-dn, search-bind-dn and search-bind-password to your active directory configuration. The «search-bind-dn» and «search-bind-password» parameters are needed, because with default settings active directory doesn’t allow anonymous users to browse the directory.

Step 2: Setting the following JVM Switch for refferals

The following JVM switch is needed with active directory LDAP servers:

-Djava.naming.referral=follow

Add this switch to your server startup script or with the admin console.

Step 3a: Basic authentication

Add the following section to your web.xml or go to Step 3b for form
based authentication.

<login-config>
  <auth-method>BASIC</auth-method>
  <realm-name>ads-realm</realm-name>
</login-config>

Step 3b: Form based authentication

Add the following section to your web.xml:

<login-config>
  <auth-method>FORM</auth-method>
  <realm-name>ads-realm</realm-name>
  <form-login-config>
    <form-login-page>/login.html</form-login-page>
    <form-error-page>/login.html</form-error-page>
  </form-login-config>
</login-config>

Create the page /login.html with a least the following code:

<html>
  <head/>
  <body>
    <form action="j_security_check" method="post">
      Username: <input type="text" name="j_username"><br/>
      Password: <input type="password" name="j_password"><br/>
      <input type="submit" value="Login"/>
    </form>
  </body>
</html>

Step 4: Adding security role to web.xml

Add at least one security role to your web.xml, in this example «userRole».

<security-role>
  <role-name>userRole</role-name>
</security-role>

Step 5: Adding security constraint to web.xml

Now we must create a security constraint and the path to the pages we want to allow only authenticated access. In this sample the access to the folder /pages/ is resticted to authenticated users in role «userRole».

<security-constraint>
  <display-name>SecurityConstraint</display-name>
  <web-resource-colletion>
    <web-resource-name>SecuredFolder</web-resource-name>
      <url-pattern>/pages/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>userRole</role-name>
    </auth-constraint>
  <user-data-constraint>
    <transport-guarantee>NONE</transport-guarantee>
  </user-data-constraint>
</security-constraint>

Step 6: Create role mapping between active directory group and role

Role mappings are defined in sun-web.xml for the Sun Java System Application Server, so add the following section:

<security-role-mapping>
  <role-name>userRole</role-name>
  <group-name>users</group-name>
</security-role-mapping>

This maps the active directory group «users» to our role «userRole»,
so only users in the group «users» can access our secured folder.

Example JAAS and AD Integration Code

package com.example.authentication.activedirectory;

import javax.security.auth.callback.*;
import java.io.IOException;

/**
 * Copyright Alvin Alexander, http://devdaily.com.
 * This code is shared here under the Attribution 3.0 Unported License.
 * See this URL for details: http://creativecommons.org/licenses/by/3.0/
 *
 * This is an implementation of CallbackHandler to pass credentials to ActiveDirectoryValidator.java.
 * See JAAS documentation for more info.
 */
public class ADCallbackHandler implements CallbackHandler
{
  private String ADUserId;
  private char[] ADPassword;

  public void handle(Callback[] callbacks) throws java.io.IOException, UnsupportedCallbackException
  {
    for (int i = 0; i < callbacks.length; i++)
    {
      if (callbacks[i] instanceof NameCallback)
      {
        NameCallback cb = (NameCallback)callbacks[i];
        cb.setName(ADUserId);
      }
      else if (callbacks[i] instanceof PasswordCallback)
      {
        PasswordCallback cb = (PasswordCallback)callbacks[i];
        cb.setPassword(ADPassword);
      }
      else
      {
        throw new UnsupportedCallbackException(callbacks[i]);
      }
    }
  }

  public void setUserId(String userid)
  {
    ADUserId = userid;
  }

  public void setPassword(String password)
  {
    ADPassword = new char[password.length()];
    password.getChars(0, ADPassword.length, ADPassword, 0);
  }

  public static void main(String[] args) throws IOException, UnsupportedCallbackException
  {
    // Test handler
    ADCallbackHandler ch = new ADCallbackHandler();
    ch.setUserId("test");
    ch.setPassword("test");

    Callback[] callbacks = new Callback[] { new NameCallback("user id:"), new PasswordCallback("password:", true) };

    ch.handle(callbacks);
  }
}

If this Java source code works for you — or doesn’t work — please leave a comment below that may help other people who are in the same Java Active Directory boat.

Configure Tomcat

Copy Files

Copy waffle-jna.jar, jna.jar and platform.jar to Tomcat’s lib directory.

JAAS Realm

Add a JAAS realm to the application context. Modify _META-INF\context.xml _of your application.

<Context>
  <Realm className="org.apache.catalina.realm.JAASRealm"
         appName="Jaas"
         userClassNames="waffle.jaas.UserPrincipal"
         roleClassNames="waffle.jaas.RolePrincipal"
         useContextClassLoader="false"
         debug="true" />
</Context>

Authentication

Modify WEB-INF\web.xml of your application.

Enable BASIC, DIGEST or FORMS authentication for this realm.

<login-config>
  <auth-method>BASIC</auth-method>
  <realm-name>Jaas</realm-name>
</login-config>

Configure security roles. The Waffle login module adds all user’s security groups (including nested and domain groups) as roles during authentication.

<security-role>
  <role-name>Everyone</role-name>
</security-role>

Restrict access to website resources. For example, to restrict the entire website to locally authenticated users add the following.

<security-constraint>
  <display-name>Waffle Security Constraint</display-name>
  <web-resource-collection>
    <web-resource-name>Protected Area</web-resource-name>
    <url-pattern>/*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
    <role-name>Everyone</role-name>
  </auth-constraint>
</security-constraint>

Login Configuration

Create a login configuration file, login.conf. This configuration file specifies how to plug the Waffle Windows Login Module.

Jaas {
    waffle.jaas.WindowsLoginModule sufficient;
};

The login.conf configuration file is passed to Java with -Djava.security.auth.login.config=<path-to-file>/login.conf.

JAAS Security Policy

Create JAAS policy configuration file, jaas.policy. This file specifies which identities are granted which permissions.

grant Principal * * {
  permission java.security.AllPermission "/*";
};

The policy file is passed to Java with -Djava.security.auth.policy=<path-to-file>/jaas.policy.

Start Tomcat

You must start Tomcat with Security Manager enabled (-security) and configure it with a login configuration and policy. For example, the following will start Tomcat using the demo login.conf and jaas.policy from the Waffle samples.

@echo off
setlocal
set JAVA_OPTS=-Djava.security.auth.login.config="C:/Program Files/Tomcat/webapps/waffle-jaas/login.conf" -Djava.security.auth.policy="C:/Program Files/Tomcat/webapps/waffle-jaas/jaas.policy"
call bin/catalina.bat run -security
endlocal

Demo Application

A demo application can be found in the Waffle distribution in the Samples\Tomcat\waffle-jaas directory. Copy the entire directory into Tomcat’s webapps directory, start Tomcat as explained above, and navigate to http://localhost:8080/waffle-jaas. You will be prompted for your Windows login, enter your Windows credentials and log-in.


Reference
What is JAAS or JACC?
https://www.ibm.com/developerworks/websphere/library/techarticles/0709_vamsi/0709_vamsi.html

AD Integration on J2EE
http://rundeck.org/docs/administration/authenticating-users.html

Oracle Leveraging JAAS
https://docs.oracle.com/cd/E16439_01/doc.1013/e13977/javaplat.htm

Declarative J2EE Authentication and Authorization with JAAS
http://www.oracle.com/technetwork/developer-tools/jdev/index-089689.html

JBOSS and JAAS
https://docs.jboss.org/jbossas/jboss4guide/r1/html/ch8.chapter.html

JAAS Example Code
http://alvinalexander.com/java/java-active-directory-jaas-example-source-code

JAAS and AD Integration Code Sample
http://code.dblock.org/2010/05/24/windowsactive-directory-authentication-tomcat-jaas-w-waffle.html

JAAS Authenication Model
http://www.javaranch.com/journal/2008/04/authentication-using-JAAS.html

JBOSS and JAAS
http://middlewaremagic.com/jboss/?p=378

J2EE and AD
https://www.gascoyne.de/archives/5


Leave a Reply

Your email address will not be published. Required fields are marked *