JAAS - Simplifying Authentication and Authorization in Enterprise Applications


I do not claim to be a master in Java Security.But I have spent good number of hours working on java security apart from my regular office hours.So I thought of sharing this information with the citizens of internet.

JAAS - Simplifying Authentication and Authorization in Enterprise Applications

Java follows a sandbox approach for security. The greatest advantage of java, Portability, is the greatest disadvantage without a security manager. By default the programs run without a security manager. There can be many malicious things that one might do with java by running a code without a security manager.

The following things describe some of those, and I am sure that after reading this article , no one would (at least hope so ;-)) dare of give any untrusted application full rights in your JVM.
The applets run in the client side and if we give the code of the applet to run with full permission then that might cause havoc after the applet code gets downloaded to the browser and the JRE (at browser end) starts executing it. Applets are nothing but a java program only. We can write the applet code in such a way that it would open a file and start appending junk data to that and finally leading to diskfull error. Consider another scenario - A hacker can write a server program running at certain port and writes an applet such that it would connect to the server and start sending data from certain files from the client's computer to the server.
Consider another example - Suppose a company gives tomcat server space in lease, and if the server does not run with security manager then we can easily write a servlet havingSystem.exit(0);this would bring the tomcat down.
With the above discussion it is clear that security is a curtail part of Java.

How Java deals with this.
We compile a java code and we get the bytecode in a .class file. Now the bytecode is something that would be interpreted by the JVM. JVM security can be set either by modifying a property file or by passing command line argument to the JVM.
JVM consults java.security which is located under $JAVA_HOM\jre\lib\security before starting with a security manager. Many other properties are set in the same property file concerning Java security. Many of the Java securities are written to interfaces so that different implementations can be adopted declaratively.
Like for example, the Java policy provider can be changed by the following property key in java.security file.
policy.provider=sun.security.provider.PolicyFile
These are the default securities settings for Sun Java.

What is JAAS?

As the name suggests (JAAS) Java Authentication and Authorization Services, it provides a framework, which is very efficient for authentication and authorization.
JAAS is an API, which provides services for authentication and authorization. These authentication and authorization are full fledged and can be used in enterprise application where security is a major concern. JAAS is inspired by PAM (Pluggable Authentication Module) or we can say JAAS to be a Java version of PAM. It was introduced as optional package in JDK 1.3, but now this has been integrated as part of standard JDK 1.4.
Authentication using JAAS.

Login Module (Class implementing javax.security.auth.spi. LoginModule)
Login Module is the place where the actual code, which does the authentication, is written. It can use various mechanisms to authenticate the username and password. That piece of code could fetch password from database according to the username and compare to the password supplied to the module. It can also use flat file or LADP for the same. Generally, in enterprise network all the authentication credentials are there at one place, might be at LDAP. So your code might fetch from LDAP also.
Login Context (javax.security.auth.login.LoginContext)
Login context is something which kicks off the authentication process by creating an empty subject. As the authentication process carries on, the subject is populated with various principals and credentials for further authorization. Login Context is not thread safe, so this class should be written in such a way that there is no class level variables or if there are variables then those should be final variables as this is not thread safe.
Subject (javax.security.auth.Subject)
Subject represents a single user, entity, system requesting for authentication or in other words the client requesting for an authentication. Before the kick off of the login process, Login Context creates an empty Subject and as the login processes, the subject is populated with security credentials and principals. If the login process is successful, then we can retrieve the subject.
Principal (Class implementing java.security.Principal interface)
Principal represents a face of a subject. It might encapsulate some feature or a property of the subject. A subject can be populated with multiple principals.
Credentials (javax.security.auth.Destroyable or javax.security.auth.Refreshable )
Credentials are nothing but a piece of information regarding the subject in consideration. This might be account number, password etc. As the credential represent some important information, the following two interfaces might be useful for creating a proper and secure credential. Suppose 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 you want the subject to destroy the credential after a specific time. In that case, you might want to implement the Destroyable interface. There is another interface provided by the JAAS infrastructure.
The process of Authentication

For authentication you need a login configuration file, which would specify the login module to be used for authentication.
There are two ways to configure the login configuration to the infrastructure.
1> Configuring in the security.java file in the following URL.
login.configuration.provider
login.config.url.n [n = whole number]
These are added to the java.security file from jdk 1.4 onwards as JAAS has been made as standard JDK 1.4 component. login.configuration.provider specifies the implementation of the login configuration file. The default for Sun?s JDK is com.sun.security.auth.login.ConfigFile.
And using login.config.url.n , we can provide the location of the actual login configuration file.
The following properties were already present in the java.securities file and can be used by JAAS for authorization
policy.provider
policy.url.n [n = whole number]
Similar to the login.configuration.provider, policy.provider provides the implementation class for the policy provider.
And the actual location of the policy file can be provided using policy.url.n
2> Passing JVM parameter.
Passing the login configuration file from the command line.
-Djava.security.auth.login.config= ="file_name"
Passing the policy file from the command line.
-Djava.security.policy= ="policy_file_name"
Working:
During the login process, the login module might have the need to communicate with the user to get user information. For this we can make use of CallbackHandler. We can pass a reference of our callback handler implementation to the LoginContext, which in turn can be used by the login module for extracting further information. After the authentication is successful, the subject is populated with principals and credentials for further use. Principals can be used further for authorization
If the Authentication is not successful, a LoingException is thrown. With this the caller can get to know that the Authentication has failed and can take action accordingly.
The following code shows a simple code for Authentication using JAAS.

# Code triggering Authentication.(com.javaranch.auth.Login)
CallbackHandler cbHandler = // my implementation of the callback handler.
LoginContext lc = new LoginContext("myApplication" , cbHandler);
try {
lc.login();
System.out.println("Successful Authentication");
Subject subject = lc.getSubject();
} catch (LoginException e) {
System.out.println("Authintication Failed (Reason) : + e.gerMessage() );
}

#Login configuration file (loginConfig.jaas)
myApplication {
com.javaranch.auth.LoginModule required;
};

#Implementaion of com.javaranch.auth.LoginModule [method login]

public boolean login() throws LoginException {
Boolean result = true;
try{
// put the code that would do the actual authentication.
// population the subject with principal of type com.javaranch.auth.MyPrincipal
MyPrincipal myPrinciple = new MyPrincipal("USE");
subject.getPrincipals().set(myPrincipal);
}catch(Exception e){
//Log exception.
Throw new LoginException("Exception encountered :" + e.getMessage() , e );
}
return result;
}

Before running the above code we need to make sure that we provide the login configuration file location in any one of the ways mentioned above.
If the login is successful, then we may store the subject for further use or else we can redirect the user for one more login process.

Authentication with SecurityManager installed.

Running the code with security manager. Bang! Getting exception. The reason is that we have to give certain permission to the code using the policy file. Make a jar using the compiled code of the application (ranch.jar)
//the below configuration grants ranch.jar required permissions for modifying the //principal (add , remove of principal from the subject.)grant codebase "file:./ranch.jar" {
permission javax.security.auth.AuthPermission "modifyPrincipals";
};
//the below code grants ranch.jar permissions for creating a
//logincontext for context myApplication.
grant codebase "file:./ranch.jar" {
permission javax.security.auth.AuthPermission "createLoginContext.myApplication";
};
To run the code with SecurityManager we need to give the following parameter to the JVM during while running the code.-Djava.security.manager along with the location of login configuration and policy file (as mentioned in the end of section "The process of Authentication") or you can directly modify the default policy file that comes with JDK.

Authorisation using JAAS.

The authorization in JAAS is nothing but the usage of standard Java authorization using permissions and policy file.The general Java policy file assigns permissions to java code bases. JAAS also uses the same model for authorization.
In JAAS the java security basically checks whether the subject has the required permissions to perform the action. You can assign various permission to principal (using a policy file) and the subject that is populated with that principal can access those resources. There is a static method in Subject method that takes care of Authorization in JAAS. Below is the code of a typical method, which needs to run a secure code.

public String getFileEncoding(Subject subject) {
return (String)Subject. doAsPrivileged (subject , new PrivilegedAction(){
public Object run() {
return System.getProperty("file.encoding");
} });
}
}

Now if the subject is not populated with principal which has permission to get the file.encoding property then it would throw exception. Apart from this, the class containing the above piece of code must have doAsPrivileged AuthPermission.
With the following changes in the policy file you can grant your code the permission to execute

doAsPriviledged method.grant codeBase "file:your_code_base.jar" {
permission javax.security.auth.AuthPermission "doAsPrivileged";
};

The below changes to the policy file would grant permission to Principal
grant principal com.javaranch.auth.MyPrincipal "USER" {
permission java.util.PropertyPermission "file.encoding", "read";
};

Conclusion.
To sum up ; JAAS provides extensible a way to provide an application a robust authentication model and resource based authorization service using standard java permissions. Another important feature of this is that it gives the application the flexibility for plugging different authentication module having different mechanism for authentication.