<< 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.
- Advanced LDAP based Authentication using LdapExtLoginModule
- LDAP based Authentication using LdapLoginModule
- Database based Authentication using DatabaseServerLoginModule
- File based Authentication using UsersRolesLoginModule
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
Comments