Security is a major component of application development. Jakarta EE provides the robust Jakarta Security specification that when paired with the Jakarta Authentication and Jakarta Authorization specifications, provides APIs that deliver end-to-end security. There are a large number of application processes that require security measures, and these specifications provide the ability to do so in a straightforward manner using annotations and minimal XML configurations. Jakarta EE compliant containers and deployment environments adhere to the constructs of the Authentication and Authorization policies to ensure that applications can be secured in a standard way and deployed across a number of different environments.
Applications consist of both protected and unprotected resources, and application security is involved with protected resources. With respect to web applications, security begins when the initial request is made to the main application URL, at which point the application container determines whether the client is authorized access to the resource. Part of this initial process is to also determine whether the client is required to be authenticated to visit the requested URL, and if so, an authentication process needs to occur. Authentication requires some type of credential from the client, oftentimes a username/password, or perhaps a JWT Token, and this credential then needs to be validated.
Once the credential has been validated, the application container then consults a security policy to determine if the client has authorization to access the requested resource. The security policy outlines different roles required to access the resource, and the validation process attempts to map the user to one of the roles which has access.
Each of the steps outlined thus far are required for front end security, providing access to requested resources. There are also security mechanisms required to protect business methods in a similar manner. Jakarta Security contains APIs for securing the entire application. Given this explanation, the following sections provide an overview of what role these specifications play in the process.
Jakarta Security is part of any container that is compatible with the Jakarta EE Platform. However, to explicitly add the Jakarta Security API to a maven application, add the following dependency:
<dependency>
<groupId>jakarta.security.enterprise</groupId>
<artifactId>jakarta.security.enterprise-api</artifactId>
<version>3.0.0</version>
</dependency>
Along with an implementation:
<dependency>
<groupId>org.glassfish.soteria</groupId>
<artifactId>jakarta.security.enterprise</artifactId>
<version>3.0.0</version>
</dependency>
The Jakarta Security specification provides a standard means for securing
Jakarta EE applications through the use of Authentication mechanisms. The
mechanisms provide implementations for the HttpAuthenticationMechanism
interface, which are used to specify how a user is authenticated, and whether
an authenticated user gains access to a requested resource. The
HttpAuthenticationMechanism
interface enables developers to work with code
configuring through annotations, rather than XML. Jakarta Security enables
security for each of the authentication methods that are defined by the Servlet
specification by providing authentication mechanisms for each:
BasicAuthenticationMechanismDefinition
annotation is
applied, if an unauthorized request is received, the container will negotiate
with the client to achieve authorization.FormAuthenticationMechanismDefinition
provides options for
specifying a login page and an error page. When the login page is specified,
the server will send the standard login form to the client, which will then
send the form contents through authentication business logic.CustomFormAuthenticationMechanism
annotation allows one to
specify a login page just like the form-based authentication, but a custom
login page incorporating logic which invokes the SecurityContext
is used.
The SecurityContext
enables a custom authentication implementation to be
applied.OpenIdAuthenticationMechanismDefinition
annotation
authenticates according to the Authorization Code flow and Refresh tokens, as
defined by the OpenID Connect specification. The mechanism requires metadata
about the OpenID Connect Provider to function properly.It should be noted that custom authentication mechanisms can be developed by
implementing the HttpAuthenticationMechanism
interface. This interface defines
methods which align with those contained within the Jakarta Authentication
ServerAuth
interface to ensure that a caller is properly authenticated and
authorized to access a requested resource.
validateRequest
(required): Provided to allow a caller to authenticate to a
resource.secureResponse
: Provided to allow post processing to occur on the response
generated by a servlet and/or servlet filter.cleanSubject
: Provided to allow for cleanup after logout.Authentication mechanisms are configured by placing an annotation respective to
the desired type of authentication, onto a Jakarta CDI bean. For instance, to
apply Basic authentication, the following annotation can be placed on an
ApplicationScoped
Jakarta CDI bean.
@BasicAuthenticationMechanismDefinition(
realmName = "myRealm")
@ApplicationScoped
public class MyClass {}
In a similar manner, form based authentication can be configured using the
following. In this case, the @LoginToContinue
method redirects the user to the
login screen or to an error page if the login attempt is unsuccessful.
@FormAuthenticationMechanismDefinition (
loginToContinue = @LoginToContinue (
loginPage = "/authenticate.html",
errorPage = "/loginError.html"))
@ApplicationScoped
public class MyClass {}
Jakarta Security defines an IdentityStore
API which can be used to
communicate with Identity Stores used to authenticate a user and obtain a
user’s defined roles. Default identity stores are provided by the compliant
container for database and LDAP authentication using the
@DatabaseIdentityStoreDefinition
or @LdapIdentityStoreDefinition
,
respectively. It is also possible to create a custom Identity store by
implementing the IdentityStore
interface. For instance, to configure an LDAP
identity store, one may do the following:
@LdapIdentityStoreDefinition(
url = "ldap://myserver:port",
callerBaseDn = "ou=caller,dc=example,dc=org",
gropuSearchBase = "ou=group,dc=example,dc=org",
groupSearchFilter = "")
@ApplicationScoped
public class MyClass {}
The SecurityContext
provides an elegant way to programmatically work with
security APIs via a Jakarta CDI bean. The SecurityContext
interface is
available at runtime, so it can be injected and utilized to do things such as
authenticate a user, check role membership, and more.
Jakarta Authentication is integrated into Jakarta Security as a low level Service Provider Implementation (SPI) for authentication mechanisms. Mentioned in the previous section, authentication mechanisms are controllers that interact with a caller and a container’s environment to obtain the caller’s credentials, validate the credentials, and pass an authenticated identity to the container. Jakarta Authentication consists of several profiles, with each telling how a specific container can integrate with and adapt to this SPI.
The authentication specification covers a wide focus on client and server authentication. An authentication context is responsible for constructing, initializing, and coordinating the invocation of one or more encapsulated authentication modules. At a high level, a typical authentication process flow works as follows:
Request and response messages are implementations of a MessageInfo
interface.
Typically, a runtime would perform the following steps to secure or validate a
message. Steps 1-4 below are performed one time, while 5 is repeated for each
message.
AuthConfigProvider
, which is used for obtaining an authentication
configuration for relevant messaging layer and application identifier.AuthConfig
from the provider:
a) ClientAuthConfig
: Client configuration
b) ServerAuthConfig
: Server configurationAuthContext
Identifier for client or server from the corresponding
AuthConfig
.ClientAuthContext
: Client context
b) ServerAuthContext
: Server ContextAn authentication module is invoked to validate a message, and it is passed a
Subject
object to receive the credentials of the source of the message and a
separate Subject object to represent the credentials of the recipient of the
message. The authentication modules contexts return AuthStatus
values with
the status, and AuthExceptions
if an exception occurs. It should be noted
that there can be more than one authentication module, and these can be invoked
independently and concurrently.
Jakarta Authorization is another integral specification that goes hand in hand with Jakarta Security. It consists of a low-level SPI for authorization policy modules, which are repositories of permissions which determine whether a subject has a given permissions to access a requested resource. This specification defines a contract between containers and authorization policy modules, which provides authorization functionality to suit the operational environment. The contract is divided into three subcontracts, which together, describe the installation and configuration of the authorization providers.
Policy
providers may be integrated with containers.Jakarta Authorization provides a standard means for working within the
boundaries of each of the three subcontracts. The Policy Configuration
Subcontract works along with the standard java.security.Policy
to provide
standard policies for a container. It also provides a means of configuring
policies using policy providers, such that the policy can be changed to reflect
what is needed for the specific environment. Jakarta Authorization also
provides a means for configuring security groups, roles, and constraints for
restricting access to particular pages within an application. The Policy
Configuration Subcontract specifies a means for ensuring that the container
will adhere to a standard method for specifying such roles and permissions.
Lastly, the Policy Decision and Enforcement Subcontract ensures that policies
are enforced in a standard way across Jakarta Servlets and Jakarta Enterprise
Beans.
Jakarta Security, Jakarta Authentication, and Jakarta Authorization specifications together provide robust security standards that can be applied to Jakarta EE applications. Since these specifications are standards across all compliant containers, developers can implement security that can be easily maintained or modified, as needed. Jakarta Security provides a means for declaratively specifying authentication types, identity stores, and for working with the API, rather than using XML. Along with Authentication and Authorization, Jakarta Security provides the tools and APIs to properly secure applications.