Introduction to Security in the Jakarta EE Platform
We are working on a fresh, updated Jakarta EE Tutorial. This section hasn’t yet been updated. |
This chapter introduces basic security concepts and security mechanisms. More information on these concepts and mechanisms can be found in the chapter on security in the Jakarta EE 9 specification.
Overview of Jakarta Security
Every enterprise that has either sensitive resources that can be accessed by many users or resources that traverse unprotected, open networks, such as the Internet, needs to be protected.
Enterprise tier and web tier applications are made up of components that are deployed into various containers. These components are combined to build a multitier enterprise application. Security for components is provided by their containers. A container provides two kinds of security: declarative and programmatic.
-
Declarative security expresses an application component’s security requirements by using either deployment descriptors or annotations.
A deployment descriptor is an XML file that is external to the application and that expresses an application’s security structure, including security roles, access control, and authentication requirements. For more information about deployment descriptors, read Using Deployment Descriptors for Declarative Security.
Annotations, also called metadata, are used to specify information about security within a class file. When the application is deployed, this information can be either used by or overridden by the application deployment descriptor. Annotations save you from having to write declarative information inside XML descriptors. Instead, you simply put annotations on the code, and the required information gets generated. For this tutorial, annotations are used for securing applications wherever possible. For more information about annotations, see Using Annotations to Specify Security Information.
-
Programmatic security is embedded in an application and is used to make security decisions. Programmatic security is useful when declarative security alone is not sufficient to express the security model of an application. For more information about programmatic security, read Using Programmatic Security.
Jakarta EE 9 includes a Security API specification that defines portable, plug-in interfaces for authentication and identity stores, and a new injectable-type SecurityContext
interface that provides an access point for programmatic security.
You can use the built-in implementations of these APIs, or define custom implementations.
More information on these concepts and mechanisms can be found in the chapter on security in the Jakarta EE 9 specification.
Other chapters in this Part discuss security requirements in web tier and enterprise tier applications, and the Jakarta Security.
-
Getting Started Securing Web Applications explains how to add security to web components, such as servlets.
-
Getting Started Securing Enterprise Applications explains how to add security to Jakarta EE components, such as enterprise beans and application clients.
-
Using Jakarta Security describes the authentication and credential validation funtionality provided by Jakarta Security, and provides examples.
A Simple Application Security Walkthrough
The security behavior of a Jakarta EE environment may be better understood by examining what happens in a simple application with a web client, a user interface, and enterprise bean business logic.
In the following example, which is taken from the Jakarta EE Specification, the web client relies on the web server to act as its authentication proxy by collecting user authentication data from the client and using it to establish an authenticated session.
Step 1: Initial Request
In the first step of this example, the web client requests the main application URL. This action is shown in Figure 1, “Initial Request”.
Since the client has not yet authenticated itself to the application environment, the server responsible for delivering the web portion of the application, hereafter referred to as the web server, detects this and invokes the appropriate authentication mechanism for this resource. For more information on these mechanisms, see Security Mechanisms.
Step 2: Initial Authentication
The web server returns a form that the web client uses to collect authentication data, such as user name and password, from the user. The web client forwards the authentication data to the web server, where it is validated by the web server, as shown in Figure 2, “Initial Authentication”. The validation mechanism may be local to a server or may leverage the underlying security services. On the basis of the validation, the web server sets a credential for the user.
Step 3: URL Authorization
The credential is used for future determinations of whether the user is authorized to access restricted resources it may request. The web server consults the security policy associated with the web resource to determine the security roles that are permitted access to the resource. The security policy is derived from annotations or from the deployment descriptor. The web container then tests the user’s credential against each role to determine whether it can map the user to the role. Figure 3, “URL Authorization” shows this process.
The web server’s evaluation stops with an "is authorized" outcome when the web server is able to map the user to a role. A "not authorized" outcome is reached if the web server is unable to map the user to any of the permitted roles.
Step 4: Fulfilling the Original Request
If the user is authorized, the web server returns the result of the original URL request, as shown in Figure 4, “Fulfilling the Original Request”.
In our example, the response URL of a web page is returned, enabling the user to post form data that needs to be handled by the business-logic component of the application. See Getting Started Securing Web Applications for more information on protecting web applications.
Step 5: Invoking Enterprise Bean Business Methods
The web page performs the remote method call to the enterprise bean, using the user’s credential to establish a secure association between the web page and the enterprise bean, as shown in Figure 5, “Invoking an Enterprise Bean Business Method”. The association is implemented as two related security contexts: one in the web server and one in the enterprise bean container.
The enterprise container is responsible for enforcing access control on the enterprise bean method. The container consults the security policy associated with the enterprise bean to determine the security roles that are permitted access to the method. The security policy is derived from annotations or from the deployment descriptor. For each role, the enterprise bean container determines whether it can map the caller to the role by using the security context associated with the call.
The container’s evaluation stops with an "is authorized" outcome when the container is able to map the caller’s credential to a role. A "not authorized" outcome is reached if the container is unable to map the caller to any of the permitted roles. A "not authorized" result causes an exception to be thrown by the container and propagated back to the calling web page.
If the call is authorized, the container dispatches control to the enterprise bean method. The result of the bean’s execution of the call is returned to the web page and ultimately to the user by the web server and the web client.
Features of a Security Mechanism
A properly implemented security mechanism will provide the following functionality:
-
Prevent unauthorized access to application functions and business or personal data (authentication)
-
Hold system users accountable for operations they perform (non-repudiation)
-
Protect a system from service interruptions and other breaches that affect quality of service
Ideally, properly implemented security mechanisms will also be
-
Easy to administer
-
Transparent to system users
-
Interoperable across application and enterprise boundaries
Characteristics of Application Security
Jakarta EE applications consist of components that can contain both protected and unprotected resources. Often, you need to protect resources to ensure that only authorized users have access. Authorization provides controlled access to protected resources. Authorization is based on identification and authentication. Identification is a process that enables recognition of an entity by a system, and authentication is a process that verifies the identity of a user, device, or other entity in a computer system, usually as a prerequisite to allowing access to resources in a system.
Authorization and authentication are not required for an entity to access unprotected resources. Accessing a resource without authentication is referred to as unauthenticated, or anonymous, access.
The characteristics of application security that, when properly addressed, help to minimize the security threats faced by an enterprise include the following.
-
Authentication: The means by which communicating entities, such as client and server, prove to each other that they are acting on behalf of specific identities that are authorized for access. This ensures that users are who they say they are.
-
Authorization, or access control: The means by which interactions with resources are limited to collections of users or programs for the purpose of enforcing integrity, confidentiality, or availability constraints. This ensures that users have permission to perform operations or access data.
-
Data integrity: The means used to prove that information has not been modified by a third party, an entity other than the source of the information. For example, a recipient of data sent over an open network must be able to detect and discard messages that were modified after they were sent. This ensures that only authorized users can modify data.
-
Confidentiality, or data privacy: The means used to ensure that information is made available only to users who are authorized to access it. This ensures that only authorized users can view sensitive data.
-
Non-repudiation: The means used to prove that a user who performed some action cannot reasonably deny having done so. This ensures that transactions can be proved to have happened.
-
Quality of Service: The means used to provide better service to selected network traffic over various technologies.
-
Auditing: The means used to capture a tamper-resistant record of security-related events for the purpose of being able to evaluate the effectiveness of security policies and mechanisms. To enable this, the system maintains a record of transactions and security information.
Security Mechanisms
The characteristics of an application should be considered when deciding the layer and type of security to be provided for applications. The following sections discuss the characteristics of the common mechanisms that can be used to secure Jakarta EE applications. Each of these mechanisms can be used individually or with others to provide protection layers based on the specific needs of your implementation.
Java SE Security Mechanisms
Java SE provides support for a variety of security features and mechanisms.
-
Java Authentication and Authorization Service (JAAS) is a set of APIs that enable services to authenticate and enforce access controls upon users. JAAS provides a pluggable and extensible framework for programmatic user authentication and authorization. JAAS is a core Java SE API and is an underlying technology for Jakarta EE security mechanisms.
-
Java Generic Security Services (Java GSS-API) is a token-based API used to securely exchange messages between communicating applications. The GSS-API offers application programmers uniform access to security services atop a variety of underlying security mechanisms, including Kerberos.
-
Java Cryptography Extension (JCE) provides a framework and implementations for encryption, key generation and key agreement, and Message Authentication Code (MAC) algorithms. Support for encryption includes symmetric, asymmetric, block, and stream ciphers. Block ciphers operate on groups of bytes; stream ciphers operate on one byte at a time. The software also supports secure streams and sealed objects.
-
Java Secure Sockets Extension (JSSE) provides a framework and an implementation for a Java version of the Secure Sockets Layer (SSL) and Transport Layer Security (TLS) protocols and includes functionality for data encryption, server authentication, message integrity, and optional client authentication to enable secure Internet communications.
-
Simple Authentication and Security Layer (SASL) is an Internet standard (RFC 2222) that specifies a protocol for authentication and optional establishment of a security layer between client and server applications. SASL defines how authentication data is to be exchanged but does not itself specify the contents of that data. SASL is a framework into which specific authentication mechanisms that specify the contents and semantics of the authentication data can fit.
Java SE also provides a set of tools for managing keystores, certificates, and policy files; generating and verifying JAR signatures; and obtaining, listing, and managing Kerberos tickets.
For more information on Java SE security, visit https://docs.oracle.com/javase/8/docs/technotes/guides/security/.
Jakarta EE Security Mechanisms
Jakarta EE security services are provided by the component container and can be implemented by using declarative or programmatic techniques (see Securing Containers). Jakarta EE security services provide a robust and easily configured security mechanism for authenticating users and authorizing access to application functions and associated data at many different layers. Jakarta EE security services are separate from the security mechanisms of the operating system.
Application-Layer Security
In Jakarta EE, component containers are responsible for providing application-layer security, security services for a specific application type tailored to the needs of the application. At the application layer, application firewalls can be used to enhance application protection by protecting the communication stream and all associated application resources from attacks.
Jakarta Security is easy to implement and configure and can offer fine-grained access control to application functions and data. However, as is inherent to security applied at the application layer, security properties are not transferable to applications running in other environments and protect data only while it is residing in the application environment. In the context of a traditional enterprise application, this is not necessarily a problem, but when applied to a web services application, in which data often travels across several intermediaries, you would need to use the Jakarta EE security mechanisms along with transport-layer security and message-layer security for a complete security solution.
The advantages of using application-layer security include the following.
-
Security is uniquely suited to the needs of the application.
-
Security is fine grained, with application-specific settings.
The disadvantages of using application-layer security include the following.
-
The application is dependent on security attributes that are not transferable between application types.
-
Support for multiple protocols makes this type of security vulnerable.
-
Data is close to or contained within the point of vulnerability.
For more information on providing security at the application layer, see Securing Containers.
Transport-Layer Security
Transport-layer security is provided by the transport mechanisms used to transmit information over the wire between clients and providers; thus, transport-layer security relies on secure HTTP transport (HTTPS) using Secure Sockets Layer (SSL). Transport security is a point-to-point security mechanism that can be used for authentication, message integrity, and confidentiality. When running over an SSL-protected session, the server and client can authenticate each other and negotiate an encryption algorithm and cryptographic keys before the application protocol transmits or receives its first byte of data. Security is active from the time the data leaves the client until it arrives at its destination, or vice versa, even across intermediaries. The problem is that the data is not protected once it gets to the destination. One solution is to encrypt the message before sending.
Transport-layer security is performed in a series of phases, as follows.
-
The client and server agree on an appropriate algorithm.
-
A key is exchanged using public-key encryption and certificate-based authentication.
-
A symmetric cipher is used during the information exchange.
Digital certificates are necessary when running HTTPS using SSL. The HTTPS service of most web servers will not run unless a digital certificate has been installed. Digital certificates have already been created for GlassFish Server.
The advantages of using transport-layer security include the following.
-
It is relatively simple, well-understood, standard technology.
-
It applies to both a message body and its attachments.
The disadvantages of using transport-layer security include the following.
-
It is tightly coupled with the transport-layer protocol.
-
It represents an all-or-nothing approach to security. This implies that the security mechanism is unaware of message contents, so that you cannot selectively apply security to portions of the message as you can with message-layer security.
-
Protection is transient. The message is protected only while in transit. Protection is removed automatically by the endpoint when it receives the message.
-
It is not an end-to-end solution, simply point-to-point.
For more information on transport-layer security, see Establishing a Secure Connection Using SSL.
Message-Layer Security
In message-layer security, security information is contained within the SOAP message and/or SOAP message attachment, which allows security information to travel along with the message or attachment. For example, a portion of the message may be signed by a sender and encrypted for a particular receiver. When sent from the initial sender, the message may pass through intermediate nodes before reaching its intended receiver. In this scenario, the encrypted portions continue to be opaque to any intermediate nodes and can be decrypted only by the intended receiver. For this reason, message-layer security is also sometimes referred to as end-to-end security.
The advantages of message-layer security include the following.
-
Security stays with the message over all hops and after the message arrives at its destination.
-
Security can be selectively applied to different portions of a message and, if using XML Web Services Security, to attachments.
-
Message security can be used with intermediaries over multiple hops.
-
Message security is independent of the application environment or transport protocol.
The disadvantage of using message-layer security is that it is relatively complex and adds some overhead to processing.
GlassFish Server supports message security using Metro, a web services stack that uses Web Services Security (WSS) to secure messages. Because this message security is specific to Metro and is not a part of the Jakarta EE platform, this tutorial does not discuss using WSS to secure messages. See the Metro User’s Guide at https://eclipse-ee4j.github.io/metro-jax-ws/.
Using Pluggable Providers
Jakarta EE includes two specifications that define SPI interfaces for pluggable security providers, Jakarta Authentication and Jakarta Security. These specifications are described in more detail in the following sections:
Jakarta Authentication
Jakarta Authentication defines a model for securing messages sent between a client and server in which the sender of a message "secures" it, and the receiver "validates" it.
The details of how messages are secured and validated are undefined by the model; support for securing and validating particular types of messages is provided by "auth modules" — implementations of the Authentication ClientAuthModule
and ServerAuthModule
interfaces — that support particular protocols or message types, and that plug in to the Authentication framework.
(Note that it is not necessary for a client and server to both use Authentication, as long as both sides process messages correctly for a given protocol.)
Authentication defines two "profiles" for integrating Authentication auth modules into Jakarta EE containers: the Servlet Container Profile, and the SOAP Profile. Each specifies how Authentication message processing must be integrated into the request processing flow of the container in question to validate incoming requests and secure outgoing responses.
In the case of the Servlet Container Profile, if a ServerAuthModule
is configured/available for a given application context, then the modules’s validateRequest()
method must be invoked (and succeed) before authorizing access and calling the target servlet, and the module’s secureResponse()
method must be called before returning a response.
Typically, a ServerAuthModule
written for the Servlet Container Profile looks for user credentials or tokens in an incoming request, and then uses them to authenticate the caller and establish the caller’s identity.
A ServerAuthModule
may also engage in a challenge/response protocol with the client, or negotiate with a third party to establish/verify the client’s identity.
As with the Servlet Container Profile, the SOAP Profile requires that validateRequest()
be called and succeed before proceeding to authorize access and perform any further processing of an incoming message, and that secureResponse()
is called for the response before it is sent.
In contrast to the Servlet Container Profile, validateRequest()
processing for SOAP messages typically involves verifying signatures on signed elements, decrypting encrypted elements, and/or establishing the identity of a SOAP actor based on a token included in the message, while secureResponse()
typically involves signing and/or encrypting elements of the outbound message.
Authentication does not define any standard or built-in ServerAuthModules; they must be provided either by the application using the module, or as a non-standard extension of a particular vendor’s Jakarta EE product.
ServerAuthModules can sometimes be directly configured for an application in a vendor-specific way, but the standard mechanism for making a ServerAuthModule
available to an application is to register a corresponding AuthConfigProvider
with the global AuthConfigFactory
.
An AuthConfigProvider
makes a ServerAuthModule
available to the container, via a series of intermediary objects, for runtime message processing.
Jakarta Security
Jakarta Security defines the following authentication-related plugin SPIs:
-
HttpAuthenticationMechanism
- An interface for modules that authenticate callers to a web application. It defines three methods that correspond to the methods of a AuthenticationServerAuthModule
, albeit with slightly different signatures. AnHttpAuthenticationMechanism
provides similar functionality to aServerAuthModule
, and the Servlet Container uses a specialServerAuthModule
to invoke the HttpAuthenticationMechanism’s methods, but HttpAuthenticationMechanisms are simpler to write, and to deploy, than are ServerAuthModules. -
IdentityStore
- This interface defines methods for validating a caller’s credentials (such as username and password) and returning group membership information. IdentityStores are invoked under the control of anIdentityStoreHandler
, which, if multiple IdentityStores are present, calls the available IdentityStores in a specific order and aggregates the results. -
RememberMeIdentityStore
- This interface is a variation on theIdentityStore
interface, intended specifically to address cases where an authenticated user’s identity should be remembered for an extended period of time, so that the caller can return to the application periodically without needing to present primary authentication credentials each time.
Implementations of these SPI interfaces are CDI beans, and, as such, applications can provide implementations that support application-specific authentication mechanisms, or validate user credentials against application-specific identity stores, simply by including them in a bean archive that is part of the deployed application.
There are also several standard, built-in implementations of HttpAuthenticationMechanism
and IdentityStore
that provide configurable support for common authentication and credential validation use cases, without the need to write custom implementations.
Because these SPIs, related annotations, and the CDI deployment mechanism are all part of standard Jakarta EE, implementations are completely portable (to the extent they do not rely internally on platform-specific APIs or libraries) and can be portably deployed to any Jakarta EE server.
Securing Containers
In Jakarta EE, the component containers are responsible for providing application security. A container provides two types of security: declarative and programmatic.
Using Annotations to Specify Security Information
Annotations enable a declarative style of programming and so encompass both the declarative and programmatic security concepts. Users can specify information about security within a class file by using annotations. GlassFish Server uses this information when the application is deployed. Not all security information can be specified by using annotations, however. Some information must be specified in the application deployment descriptors.
Specific annotations that can be used to specify security information within an enterprise bean class file are described in Securing an Enterprise Bean Using Declarative Security. Getting Started Securing Web Applications, describes how to use annotations to secure web applications where possible. Deployment descriptors are described only where necessary.
For more information on annotations, see Further Information about Security.
Using Deployment Descriptors for Declarative Security
Declarative security can express an application component’s security requirements by using deployment descriptors. Because deployment descriptor information is declarative, it can be changed without the need to modify the source code. At runtime, the Jakarta EE server reads the deployment descriptor and acts upon the corresponding application, module, or component accordingly. Deployment descriptors must provide certain structural information for each component if this information has not been provided in annotations or is not to be defaulted.
This part of the tutorial does not document how to create deployment descriptors; it describes only the elements of the deployment descriptor relevant to security. NetBeans IDE provides tools for creating and modifying deployment descriptors.
Different types of components use different formats, or schemas, for their deployment descriptors. The security elements of deployment descriptors discussed in this tutorial include the following.
-
Web components may use a web application deployment descriptor named
web.xml
.The schema for web component deployment descriptors is provided in Chapter 14 of the Jakarta Servlet 5.0 specification, which can be downloaded from https://jakarta.ee/specifications/servlet/5.0/.
-
Jakarta Enterprise Beans components may use an enterprise bean deployment descriptor named
META-INF/ejb-jar.xml
, contained in the enterprise bean JAR file.The schema for enterprise bean deployment descriptors is provided in Chapter 13 of the Jakarta Enterprise Beans 4.0 Core Contracts and Requirements Specification, which can be downloaded from https://jakarta.ee/specifications/enterprise-beans/4.0/.
Using Programmatic Security
Programmatic security is embedded in an application and is used to make security decisions.
Programmatic security is useful when declarative security alone is not sufficient to express the security model of an application.
The API for programmatic security consists of methods of the Jakarta Security SecurityContext
interface, and methods of the enterprise bean EJBContext
interface and the servlet HttpServletRequest
interface.
These methods allow components to make business-logic decisions based on the security role of the caller or remote user.
Programmatic security is discussed in more detail in the following sections:
Securing GlassFish Server
This tutorial describes deployment to GlassFish Server, which provides highly secure, interoperable, and distributed component computing based on the Jakarta EE security model. GlassFish Server supports the Jakarta EE 9 security model. You can configure GlassFish Server for the following purposes.
-
Adding, deleting, or modifying authorized users. For more information on this topic, see Working with Realms, Users, Groups, and Roles.
-
Configuring secure HTTP and Internet Inter-Orb Protocol (IIOP) listeners.
-
Configuring secure Java Management Extensions (JMX) connectors.
-
Adding, deleting, or modifying existing or custom realms.
-
Defining an interface for pluggable authorization providers using Jakarta Authorization. Jakarta Authorization defines security contracts between GlassFish Server and authorization policy modules. These contracts specify how the authorization providers are installed, configured, and used in access decisions.
-
Using pluggable audit modules.
-
Customizing authentication mechanisms. All implementations of Jakarta EE 9 compatible web containers are required to support the Servlet Profile of Jakarta Authentication, which offers an avenue for customizing the authentication mechanism applied by the web container on behalf of one or more applications.
-
Setting and changing policy permissions for an application.
Working with Identity Stores
An identity store is a database or directory (store) that contains identity information about a collection of users that includes an application’s callers. An identity store holds callers names, group membership information, and information sufficient to allow it to validate a caller’s credentials. An identity store may also contain other information, such as globally unique caller identifiers or other caller attributes.
As specified in the Jakarta EE Security API, the IdentityStore
interface provides an abstraction of an identity store.
Implementations of the IdentityStore
interface interact with identity stores to authenticate users and to retrieve caller group information.
Most often, an implementation of the IdentityStore
interface interacts with an external identity store, such as an LDAP server, but it can also manage user account data itself.
The IdentityStore
interface is intended primarily for use by the HttpAuthenticationMechanism
(also specified in the Jakarta Security), but can be used by other implementations such as a JASPIC ServerAuthModule
or a container’s built-in authentication mechanisms.
Using the HttpAuthenticationMechanism
and IdentityStore
implementations, both built-in and custom, provides a significant advantage over the BASIC and FORM mechanisms defined by Servlet 5.0 (and previous versions) and configured declaratively using <login-config>
in web.xml
, because it allows an application to control the identity stores it will authenticate against in a standard, portable way.
An application can provide its own IdentityStore
, or use the built in LDAP or Database identity store implementations of the interface.
For details about the IdentityStore
interfaces and examples of their usage, see Overview of the Identity Store Interfaces.
Working with Realms, Users, Groups, and Roles
You often need to protect resources to ensure that only authorized users have access. See Characteristics of Application Security for an introduction to the concepts of authentication, identification, and authorization.
This section discusses setting up users so that they can be correctly identified and either given access to protected resources or denied access if they are not authorized to access the protected resources. To authenticate a user, you need to follow these basic steps.
-
The application developer writes code to prompt for a user name and password. The various methods of authentication are discussed in Specifying Authentication Mechanisms.
-
The application developer communicates how to set up security for the deployed application by use of a metadata annotation or deployment descriptor. This step is discussed in Setting Up Security Roles.
-
The server administrator sets up authorized users and groups in GlassFish Server. This is discussed in Managing Users and Groups in GlassFish Server.
-
The application deployer maps the application’s security roles to users, groups, and principals defined in GlassFish Server. This topic is discussed in Figure 6, “Mapping Roles to Users and Groups”.
By default, group principal names are mapped to roles of the same name. |
What Are Realms, Users, Groups, and Roles?
A realm is a security policy domain defined for a web or application server. A realm contains a collection of users, who may or may not be assigned to a group. Managing users in GlassFish Server is discussed in Managing Users and Groups in GlassFish Server.
An application will often prompt for a user name and password before allowing access to a protected resource. After the user name and password have been entered, that information is passed to the server, which either authenticates the user and sends the protected resource or does not authenticate the user, in which case access to the protected resource is denied. This type of user authentication is discussed in Specifying an Authentication Mechanism in the Deployment Descriptor.
In some applications, authorized users are assigned to roles. In this situation, the role assigned to the user in the application must be mapped to a principal or group defined on the application server. Figure 6, “Mapping Roles to Users and Groups” shows this. More information on mapping roles to users and groups can be found in Setting Up Security Roles.
The following sections provide more information on realms, users, groups, and roles.
What Is a Realm?
The protected resources on a server can be partitioned into a set of protection spaces, each with its own authentication scheme and/or authorization database containing a collection of users and groups. A realm is a complete database of users and groups identified as valid users of one or more applications and controlled by the same authentication policy.
The Jakarta EE server authentication service can govern users in multiple realms.
The file
, admin-realm
, and certificate
realms come preconfigured for GlassFish Server.
In the file
realm, the server stores user credentials locally in a file named keyfile
.
You can use the Administration Console to manage users in the file
realm.
When using the file
realm, the server authentication service verifies user identity by checking the file
realm.
This realm is used for the authentication of all clients except for web browser clients that use HTTPS and certificates.
In the certificate
realm, the server stores user credentials in a certificate database.
When using the certificate
realm, the server uses certificates with HTTPS to authenticate web clients.
To verify the identity of a user in the certificate
realm, the authentication service verifies an X.509 certificate.
For step-by-step instructions for creating this type of certificate, see Working with Digital Certificates.
The common name field of the X.509 certificate is used as the principal name.
The admin-realm
is also a file
realm and stores administrator user credentials locally in a file named admin-keyfile
.
You can use the Administration Console to manage users in this realm in the same way you manage users in the file
realm.
For more information, see Managing Users and Groups in GlassFish Server.
What Is a User?
A user is an individual or application program identity that has been defined in GlassFish Server. In a web application, a user can have associated with that identity a set of roles that entitle the user to access all resources protected by those roles. Users can be associated with a group.
A Jakarta EE user is similar to an operating system user. Typically, both types of users represent people. However, these two types of users are not the same. The Jakarta EE server authentication service has no knowledge of the user name and password you provide when you log in to the operating system. The Jakarta EE server authentication service is not connected to the security mechanism of the operating system. The two security services manage users that belong to different realms.
What Is a Group?
A group is a set of authenticated users, classified by common traits, defined in GlassFish Server.
A Jakarta EE user of the file
realm can belong to a group in GlassFish Server.
(A user in the certificate
realm cannot.)
A group in GlassFish Server is a category of users classified by common traits, such as job title or customer profile.
For example, most customers of an e-commerce application might belong to the CUSTOMER
group, but the big spenders would belong to the PREFERRED
group.
Categorizing users into groups makes it easier to control the access of large numbers of users.
A group in GlassFish Server has a different scope from a role. A group is designated for the entire GlassFish Server, whereas a role is associated only with a specific application in GlassFish Server.
What Is a Role?
A role is an abstract name for the permission to access a particular set of resources in an application. A role can be compared to a key that can open a lock. Many people might have a copy of the key. The lock doesn’t care who you are, only that you have the right key.
Some Other Terminology
The following terminology is also used to describe the security requirements of the Jakarta EE platform.
-
A principal is an entity that can be authenticated by an authentication protocol in a security service that is deployed in an enterprise. A principal is identified by using a principal name and authenticated by using authentication data.
-
A security policy domain, also known as a security domain or realm, is a scope over which a common security policy is defined and enforced by the security administrator of the security service.
-
Security attributes are a set of attributes associated with every principal. The security attributes have many uses: for example, access to protected resources and auditing of users. Security attributes can be associated with a principal by an authentication protocol.
-
A credential is an object that contains or references security attributes used to authenticate a principal for Jakarta EE services. A principal acquires a credential upon authentication or from another principal that allows its credential to be used.
Managing Users and Groups in GlassFish Server
Follow these steps for managing users before you run the tutorial examples.
To Add Users to GlassFish Server
-
Start GlassFish Server, if you haven’t already done so.
Information on starting GlassFish Server is available in Starting and Stopping GlassFish Server.
-
Start the Administration Console, if you haven’t already done so.
To start the Administration Console, open a web browser and specify the URL http://localhost:4848/. If you changed the default Admin port during installation, enter the correct port number in place of
4848
. -
In the navigation tree, expand the Configurations node, then expand the server-config node.
-
Expand the Security node.
-
Expand the Realms node.
-
Select the realm to which you are adding users.
-
Select the
file
realm to add users you want to access applications running in this realm.For the example security applications, select the
file
realm. -
Select the
admin-realm
to add users you want to enable as system administrators of GlassFish Server.You cannot add users to the
certificate
realm by using the Administration Console. In thecertificate
realm, you can add only certificates. For information on adding (importing) certificates to thecertificate
realm, see Adding Users to the Certificate Realm.
-
-
On the Edit Realm page, click Manage Users.
-
On the File Users or Admin Users page, click New to add a new user to the realm.
-
On the New File Realm User page, enter values in the User ID, Group List, New Password, and Confirm New Password fields.
For the Admin Realm, the Group List field is read-only, and the group name is
asadmin
. Restart GlassFish Server and the Administration Console after you add a user to the Admin Realm.For more information on these properties, see Working with Realms, Users, Groups, and Roles.
For the example security applications, specify a user with any name and password you like, but make sure that the user is assigned to the group
TutorialUser
. The user name and password are case-sensitive. Keep a record of the user name and password for working with the examples later in this tutorial. -
Click OK to add this user to the realm, or click Cancel to quit without saving.
Setting Up Security Roles
When you design an enterprise bean or web component, you should always think about the kinds of users who will access the component.
For example, a web application for a human resources department might have a different request URL for someone who has been assigned the role of DEPT_ADMIN
than for someone who has been assigned the role of DIRECTOR
.
The DEPT_ADMIN
role may let you view employee data, but the DIRECTOR
role enables you to modify employee data, including salary data.
Each of these security roles is an abstract logical grouping of users that is defined by the person who assembles the application.
When an application is deployed, the deployer will map the roles to security identities in the operational environment, as shown in Figure 6, “Mapping Roles to Users and Groups”.
For Jakarta EE components, you define security roles using the @DeclareRoles
and @RolesAllowed
metadata annotations.
The following is an example of an application in which the role of DEPT-ADMIN
is authorized for methods that review employee payroll data, and the role of DIRECTOR
is authorized for methods that change employee payroll data.
The enterprise bean would be annotated as shown in the following code:
import jakarta.annotation.security.DeclareRoles;
import jakarta.annotation.security.RolesAllowed;
...
@DeclareRoles({"DEPT-ADMIN", "DIRECTOR"})
@Stateless public class PayrollBean implements Payroll {
@Resource SessionContext ctx;
@RolesAllowed("DEPT-ADMIN")
public void reviewEmployeeInfo(EmplInfo info) {
oldInfo = ... read from database;
// ...
}
@RolesAllowed("DIRECTOR")
public void updateEmployeeInfo(EmplInfo info) {
newInfo = ... update database;
// ...
}
...
}
For a servlet, you can use the @HttpConstraint
annotation within the @ServletSecurity
annotation to specify the roles that are allowed to access the servlet.
For example, a servlet might be annotated as follows:
@WebServlet(name = "PayrollServlet", urlPatterns = {"/payroll"})
@ServletSecurity(
@HttpConstraint(transportGuarantee = TransportGuarantee.CONFIDENTIAL,
rolesAllowed = {"DEPT-ADMIN", "DIRECTOR"}))
public class GreetingServlet extends HttpServlet { ... }
These annotations are discussed in more detail in Specifying Security for Basic Authentication Using Annotations and Securing an Enterprise Bean Using Declarative Security.
After users have provided their login information and the application has declared what roles are authorized to access protected parts of an application, the next step is to map the security role to the name of a user, or principal.
Mapping Roles to Users and Groups
When you are developing a Jakarta EE application, you don’t need to know what categories of users have been defined for the realm in which the application will be run. In the Jakarta EE platform, the security architecture provides a mechanism for mapping the roles defined in the application to the users or groups defined in the runtime realm.
The role names used in the application are often the same as the group names defined in GlassFish Server. Jakarta Security requires that group principal names are mapped to roles of the same name by default. Accordingly, the Default Principal To Role Mapping setting is enabled by default on the Security page of the GlassFish Server Administration Console. All the tutorial security examples use default principal-to-role mapping. With that setting enabled, if the group name defined on GlassFish Server matches the role name defined in the application, there is no need to use the runtime deployment descriptor to provide a mapping. The application server will implicitly make this mapping, as long as the names of the groups and roles match.
If the role names used in an application are not the same as the group names defined on the server, use the runtime deployment descriptor to specify the mapping.
The following example demonstrates how to do this mapping in the glassfish-web.xml
file, which is the file used for web applications:
<glassfish-web-app>
...
<security-role-mapping>
<role-name>Mascot</role-name>
<principal-name>Duke</principal-name>
</security-role-mapping>
<security-role-mapping>
<role-name>Admin</role-name>
<group-name>Director</group-name>
</security-role-mapping>
...
</glassfish-web-app>
A role can be mapped to specific principals, specific groups, or both.
The principal or group names must be valid principals or groups in the current default realm or in the realm specified in the login-config
element.
In this example, the role of Mascot
used in the application is mapped to a principal, named Duke
, that exists on the application server.
Mapping a role to a specific principal is useful when the person occupying that role may change.
For this application, you would need to modify only the runtime deployment descriptor rather than search and replace throughout the application for references to this principal.
Also in this example, the role of Admin
is mapped to a group of users assigned the group name of Director
.
This is useful because the group of people authorized to access director-level administrative data has to be maintained only in GlassFish Server.
The application developer does not need to know who these people are, but only needs to define the group of people who will be given access to the information.
The role-name
must match the role-name
in the security-role
element of the corresponding deployment descriptor or the role name defined in a @DeclareRoles
annotation.
Establishing a Secure Connection Using SSL
Secure Sockets Layer (SSL) technology is security that is implemented at the transport layer (see Transport-Layer Security for more information about transport-layer security). SSL allows web browsers and web servers to communicate over a secure connection. In this secure connection, the data is encrypted before being sent and then is decrypted upon receipt and before processing. Both the browser and the server encrypt all traffic before sending any data.
SSL addresses the following important security considerations.
-
Authentication: During your initial attempt to communicate with a web server over a secure connection, that server will present your web browser with a set of credentials in the form of a server certificate (also called a public key certificate). The purpose of the certificate is to verify that the site is who and what it claims to be. In some cases, the server may request a certificate proving that the client is who and what it claims to be; this mechanism is known as client authentication.
-
Confidentiality: When data is being passed between the client and the server on a network, third parties can view and intercept this data. SSL responses are encrypted so that the data cannot be deciphered by the third party and the data remains confidential.
-
Integrity: When data is being passed between the client and the server on a network, third parties can view and intercept this data. SSL helps guarantee that the data will not be modified in transit by that third party.
The SSL protocol is designed to be as efficient as securely possible.
However, encryption and decryption are computationally expensive processes from a performance standpoint.
It is not strictly necessary to run an entire web application over SSL, and it is customary for a developer to decide which pages require a secure connection and which do not.
Pages that might require a secure connection include those for login, personal information, shopping cart checkouts, or credit card information transmittal.
Any page within an application can be requested over a secure socket by simply prefixing the address with https:
instead of http:
.
Any pages that absolutely require a secure connection should check the protocol type associated with the page request and take the appropriate action if https:
is not specified.
Using name-based virtual hosts on a secured connection can be problematic. This is a design limitation of the SSL protocol itself. The SSL handshake, whereby the client browser accepts the server certificate, must occur before the HTTP request is accessed. As a result, the request information containing the virtual host name cannot be determined before authentication, and it is therefore not possible to assign multiple certificates to a single IP address. If all virtual hosts on a single IP address need to authenticate against the same certificate, the addition of multiple virtual hosts should not interfere with normal SSL operations on the server. Be aware, however, that most client browsers will compare the server’s domain name against the domain name listed in the certificate, if any; this is applicable primarily to official certificates signed by a certificate authority (CA). If the domain names do not match, these browsers will display a warning to the client. In general, only address-based virtual hosts are commonly used with SSL in a production environment.
Verifying and Configuring SSL Support
As a general rule, you must address the following issues to enable SSL for a server.
-
There must be a
Connector
element for an SSL connector in the server deployment descriptor. -
There must be valid keystore and certificate files.
-
The location of the keystore file and its password must be specified in the server deployment descriptor.
An SSL HTTPS connector is already enabled in GlassFish Server.
For testing purposes and to verify that SSL support has been correctly installed, load the default introduction page with a URL that connects to the port defined in the server deployment descriptor:
https://localhost:8181/
The https
in this URL indicates that the browser should be using the SSL protocol.
The localhost
in this example assumes that you are running the example on your local machine as part of the development process.
The 8181
in this example is the secure port that was specified where the SSL connector was created.
If you are using a different server or port, modify this value accordingly.
The first time that you load this application, the New Site Certificate or Security Alert dialog box appears. Click Next to move through the series of dialog boxes, and click Finish when you reach the last dialog box. The certificates will appear only the first time. When you accept the certificates, subsequent hits to this site assume that you still trust the content.
Further Information about Security
For more information about security in Jakarta EE applications, see
-
Jakarta EE 9 specification:
https://jakarta.ee/specifications/platform/9/ -
Jakarta Security 3.0:
https://jakarta.ee/specifications/security/3.0/ -
Jakarta Authentication 3.0:
https://jakarta.ee/specifications/authentication/3.0/ -
Jakarta Enterprise Beans 4.0 specification:
https://jakarta.ee/specifications/enterprise-beans/4.0/ -
Jakarta Enterprise Web Services 2.0 specification:
https://jakarta.ee/specifications/enterprise-ws/2.0/ -
Java SE security information:
https://docs.oracle.com/javase/8/docs/technotes/guides/security/ -
Jakarta Servlet 6.0 specification:
https://jakarta.ee/specifications/servlet/6.0/ -
Jakarta Authorization 2.1 specification:
https://jakarta.ee/specifications/authorization/2.1/