Java Authentication and Authorization Service (JAAS) – Features, Architecture | How does JAAS Work?

Java authentication and authorization services: Java Authentication and Authorization Service (JAAS) is the API, which provides flexible and scalable standard security features for your applications. JAAS helps in the enforcement of access control over the resources to be secured. With the release of JAAS, Java has evolved as the general-purpose language for the development of applications that need login and access control.

JAAS helps in the two important aspects of security – authentication, and authorization. Reliability and security can be assured by authenticating the user who is trying to access the access-controlled object or trying to execute the java code. The code may be running as an application, an applet, a bean, or a servlet. Authorization is assuring whether the user has the permission or privilege to do the action performed.

Features Supported by the Java Authentication and Authorization Service(JAAS)

  • The authentication is being done on the basis of who is executing the code irrespective of the fact that the code is an application, an applet, a bean, or a servlet.
  • Authorizing the users for the permission granted to them for the action being performed by them.
  • JAAS is a pure Java technology.
  • The flexible access policy for users.
  • Role-based authorization.

How does JAAS Work?

While using a JAAS in an Application several SPIs are Involved.

CallBack Handler: It is used for collecting User Credentials and is optionally given while creating a LoginContext.

Configuration: It is responsible for loading LoginModule Implementations and can be given optional at the time of LoginContext Creation.

Login Module: It is used effectively for authenticating users.

We use default Implementation for Configuration API and provide our own implementations for both CallBack Handler and LoginModule APIs.

JAAS Architecture

JAAS has definitely simplified the java security development by introducing an abstraction layer between the application and the authentication and authorization mechanism being used. This abstraction helps in using the different security mechanisms of our choice without changing the code in the application.

The application directly interacts with the LoginContext. LoginContext works as the interface between the application and the set of one or more LoginModules, which are directly configured. These LoginModules are actually responsible for handling the authentication using a security infrastructure.

JAAS also provides reference LoginModule implementations and we can develop our switch modules. A simple configuration file is just enough to help in setting up the application with a choice of implementations. see figure below.

JAAS Architecture

Abstract JAAS Authentication Provider

Abstract JAAS Authentication Provider is responsible for providing the JAAS Authentication Provider Implementations. SubClasses need to implement a method that creates LoginContext. JAAS Authentication Provider has plenty of dependencies that can be injected into it and all of them are discussed below.

Do Read:

CallBack Handler Implementation

Before diving into the Login Module Implementation let’s get started with the CallBack Handler Implementation Interface for gathering the User Credentials. It includes a Single Method named Handler() that accepts an array of CallBacks. Java Authentication and Authorization Service use several implementations namely Name CallBack and Password CallBack, etc. for collecting the User Name and Passwords respectively.

CallBack Handler Interface Implementation

In order to Prompt and read the User Name we have used

NameCallback nameCallback = (NameCallback) callback;
nameCallback.setName(console.readLine(nameCallback.getPrompt()));

In the same way, to prompt and read the password we use the following

PasswordCallback passwordCallback = (PasswordCallback) callback; 
passwordCallback.setPassword(console.readPassword(passwordCallback.getPrompt()));

Login Module Implementation

For better understanding, we will provide a simple implementation storing the hard-coded users. It is called as Memory InLogin Module.

Login Module Implementation

In the later modules let us learn in detail about the implementation of more important methods such as initialize(), login(), and commit().

Initialize()

Login Module is loaded at first and then initialized with a subject named CallBack Handler. In addition, LoginModules can use a Map for sharing data among themselves and one more Map for storing Private Configuration Data.

Initialize Implementation

login()

In the login() method we use a CallbackHandler.handle() Method with a Name CallBack and Password CallBack so as to prompt and retrieve the User Name and Password. Later, we will compare these Credentials with the hard-cored ones.

Login Implementation

The login should return true for successful operation and a false for the failed login.

commit()

If all calls to LoginModule#login succeed then we will update the subject with one more principal.

Commit Implementation

Or else abort() method is called.

LoginModule implementation is ready to use and we can configure it so that it can be loaded dynamically using Configuration Service Provider.

Login Module Configuration

JAAS uses the Configuration Service Provider in order to Load Login Modules during the run time. By default it uses ConfigFile Implementation in which Login Modules are configured through a Login File.

jaasApplication {
com.baeldung.jaas.loginmodule.InMemoryLoginModule required debug=true;
};

You can witness in the above example we have provided a fully qualified class name of the LoginModule Implementation, debugging option, and a required flag.

Note: You can also specify the login file using the java.security.auth.login.config system property:

JAAS Authority Granter

JAAS works using Principals. In fact, Roles are represented as Principals in JAAS. Spring Security works using the Authentication Objects and each Authentication Object includes a single principal, multiple Granted Authorities. To Provide Mapping between the different concepts Spring Security’s JAAS Package has an Authority Granter Interface.

Authority Granter is the one responsible for inspecting a principal and returning a Set of Strings denoting the authorities assigned to the principal. For each of the returned Authority String JAAS AbstractJaasAuthenticationProvider creates a JaasGrantedAuthority having the authority string and the JAAS principal that the AuthorityGranter was passed. JAAS Authentication Provider gets the JAAS Principals by successfully authenticating the user credentials taking the help of the JAAS LoginModule and then accesses the LoginContext and returns.

A call to LoginContext.getSubject().getPrincipals() is made for each and every resulting principal passed to Authority Granter defined against the AbstractJaasAuthenticationProvider.setAuthorityGranters(List) Property.

Spring Security doesn’t have any Production Authority Granter provided that every JAAS Principal has an Implementation Specific Meaning. However, you will have a Test Authority Granter in the unit tests that tell us a Simple Authority Granter Implementation.