PicketBox Authentication

<< Go Back To PicketBox Overview

 

PicketBox (formely JBoss Security) provides JAAS based authentication facilities for Java applications.

 

 


Pre-requisites

  • If you are running in JBoss Application Server v5.0 and beyond, the dependencies of PicketBox are available. In this case, you only need to download the PicketBox core libraries.
  • If you are running in a non JBoss AS 5+ environment, then you will need to download some dependencies for PicketBox apart from the core libraries.

 

Authentication

It is based on JAAS, available as part of the JDK.

 

We provide simple file based authentication, Database based authentication and LDAP based authentication. Choose the login module that is suitable for you.

 

Simple Example

For a simple example, please look at the section on using annotations (with no external xml config file).

 

Contents

In this article, we look at the following scenarios:

  • You want authentication but do not want to hard code the configuration. This case, you can use the xml file based configuration.
  • You do not want to use xml configuration and want everything via Java annotations.

 

PicketBox Authentication using an XML configuration

Sample Code

 

//Imports
import java.security.Principal;
import java.util.HashMap;
import java.util.Map;

import javax.security.auth.Subject;

import org.jboss.security.AuthenticationManager;
import org.picketbox.config.PicketBoxConfiguration;
import org.picketbox.factories.SecurityFactory;

//Arbitrary Method for authentication
private static void testAuthentication()
{
      //The security domain name is the one used in the configuration file listing the modules
      String securityDomainName = "test";
      SecurityFactory.prepare();
      try
      { 
         String configFile = "config/authentication.conf";
         PicketBoxConfiguration idtrustConfig = new PicketBoxConfiguration();
         idtrustConfig.load(configFile);

         AuthenticationManager am = SecurityFactory.getAuthenticationManager(securityDomainName);
         if(am == null)
            throw new RuntimeException("Authentication Manager is null"); 

         Subject subject = new Subject();
         Principal principal = getPrincipal("anil");
         Object credential = new String("pass");

         boolean result = am.isValid(principal, credential); 
         if(result == false)
            throw new RuntimeException("Authentication Failed");
         
         result = am.isValid(principal, credential, subject);
         if(result == false)
            throw new RuntimeException("Authentication Failed");
         
         if(subject.getPrincipals().size() < 1)
            throw new RuntimeException("Subject has zero principals"); 
         System.out.println("Authentication Successful");
      }
      finally
      {
         SecurityFactory.release();
      }
 }

//Simple method to return a principal   
private Principal getPrincipal(final String name)
{
     return new Principal()
     {
         public String getName()
         {
            return name;
         }
      };
}

 

Let us take a look at authentication.conf

 

<?xml version='1.0'?> 
 
<policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="urn:jboss:security-config:5.0"
         xmlns="urn:jboss:security-config:5.0"
         xmlns:jbxb="urn:jboss:security-config:5.0">
   <application-policy name = "test"> 
       <authentication>
          <login-module code = "org.jboss.security.auth.spi.UsersRolesLoginModule"
             flag = "required">  
          </login-module> 
       </authentication> 
    </application-policy>  
</policy>

 

In this example, we had two properties files in the classpath:

 

defaultUsers.properties

anil=pass

 

defaultRoles.properties

anil=validuser

 

This example was very simple. It made use of a file based login module.  In your enterprise application, either the ldap or db based login module is recommended.

 

To explain the example code, we use SecurityFactory.prepare() and SecurityFactory.release() block in a try/finally structure.

PicketBox Authentication in a JBoss Application Server 5 environment

 

Sometime you want the PicketBox authentication results to be propagated to calls to other components such as EJBs, Web applications etc. As long as the other components use the same security domain name, you can have end to end seamless security.

public void testAuthenticationUsingSecurityContext() throws Exception
   {
      SecurityFactory.prepare();
      try
      {
         String securityDomainName = "test";
         String configFile = "config/authentication.conf";
         PicketBoxConfiguration idtrustConfig = new PicketBoxConfiguration();
         idtrustConfig.load(configFile);
         //Note: This is the most important line where you establish a security context
         SecurityContext securityContext = SecurityFactory.establishSecurityContext(securityDomainName); 
         
         AuthenticationManager am = securityContext.getAuthenticationManager(); 
         assertNotNull(am);

         Subject subject = new Subject();
         Principal principal = getPrincipal("anil");
         Object credential = new String("pass");
         
         boolean result = am.isValid(principal, credential); 
         assertTrue("Valid Auth", result);
         result = am.isValid(principal, credential, subject);
         assertTrue("Valid Auth", result);
         assertTrue("Subject has principals", subject.getPrincipals().size() > 0); 
         
         securityContext.getUtil().createSubjectInfo(principal, credential, subject);
         assertEquals("UserName == anil", "anil", securityContext.getUtil().getUserName());
         assertEquals("subject is equal", subject, securityContext.getUtil().getSubject());
         //You may make call outs to other components here
         ...
     }
      finally
      {
         securityContext.getUtil().setSubjectInfo(null);
         SecurityFactory.release();
      }
   }

Note: If you plan to reuse the security domain configuration in conf/login-config.xml and not provide your own configuration file in JBossAS, you can remove the variable idtrustconfig and loading the configuration file above.

PicketBox Authentication using Annotations And No External XML Config File

Sometime developers do not want to deal with xml files but are content in using Annotations. In this case, the @Authentication is the best choice.

 

package org.picketbox.test.pojos;

import org.jboss.security.annotation.Authentication;
import org.jboss.security.annotation.Module;
import org.jboss.security.annotation.ModuleOption;

/**
 * Pojo with the <code>Authentication</code> annotation 
 */
@Authentication(modules={@Module(code = UsersRolesLoginModule.class, options =
{@ModuleOption})})
public class AuthenticationAnnotatedPOJO
{ 
}

 

This uses the the UsersRolesLoginModule and provide two properties files, users.properties and roles.properties in the classpath.

 

The test code would look:

 

@Test
   public void testAuthenticationAnnotation() throws Exception
   {
      AuthenticationAnnotatedPOJO pojo = new AuthenticationAnnotatedPOJO();
      
      PicketBoxProcessor processor = new PicketBoxProcessor(); 
      processor.setSecurityInfo("anil", "pass");
      processor.process(pojo);
      

      Principal anil = new SimplePrincipal("anil");
      assertEquals("Principal == anil", anil, processor.getCallerPrincipal());
      Subject callerSubject = processor.getCallerSubject();
      assertNotNull("Subject is not null", callerSubject);
      assertTrue("Subject contains principal anil", callerSubject.getPrincipals().contains(anil));  
   }

Annotation: @Authentication

Details are provided at PicketBoxSecurityAnnotations

 

 

<< Go Back To PicketBox Overview