Chapter 24 Introduction to
Security in the Java EE Platform

The chapters in Part VII discuss security requirements in web tier and
enterprise tier applications. 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.

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 Java EE 6 specification. This document is available
for download online at http://www.jcp.org/en/jsr/detail?id=316.

In this tutorial, security requirements are also addressed in the following
chapters.

Overview of Java EE Security

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.

A Simple Security Example

The security behavior of a Java 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 Java EE 6 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 24–1.

Figure 24–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 24–2.
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.

Figure 24–2 Initial Authentication

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 24–3 shows this process.

Figure 24–3 URL Authorization

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 24–4.

Figure 24–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 Chapter 25, 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 24–5. The association is implemented as two related security contexts:
one in the web server and one in the EJB container.

Figure 24–5 Invoking an Enterprise Bean Business Method

The EJB 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 EJB 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

Java 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 Java 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):
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 Java EE security mechanisms.

Simple Authentication and Security Layer (SASL): 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.

Java EE Security Mechanisms

Java EE security services are provided by the component container and
can be implemented by using declarative or programmatic techniques (see Securing Containers). Java 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. Java EE security services are separate from the
security mechanisms of the operating system.

Application-Layer Security

In Java 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.

Java EE 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 Java 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.

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 the 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.

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.

The 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 Java EE platform,
this tutorial does not discuss using WSS to secure messages. See the Metro
User’s Guide at https://metro.dev.java.net/guide/.

Securing Containers

In Java 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. The 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.

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 Java 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 Java
Servlet 3.0 specification (JSR 315), which can be downloaded from http://jcp.org/en/jsr/detail?id=315.

Enterprise JavaBeans components may use an EJB deployment
descriptor named META-INF/ejb-jar.xml, contained in the
EJB JAR file.

The schema for enterprise bean deployment descriptors
is provided in Chapter 19 of the EJB 3.1 specification (JSR 318), which can
be downloaded from http://jcp.org/en/jsr/detail?id=318.

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 EJBContext interface
and the 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 the GlassFish Server

This tutorial describes deployment to the GlassFish Server, which provides
highly secure, interoperable, and distributed component computing based on
the Java EE security model. GlassFish Server supports the Java EE 6 security
model. You can configure GlassFish Server for the following purposes:

Defining an
interface for pluggable authorization providers using Java Authorization Contract
for Containers (JACC). JACC defines security contracts between the 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 Java EE 6 compatible Servlet containers are required to support
the Servlet Profile of JSR 196, 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 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 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 application deployer maps the application’s security
roles to users, groups, and principals defined on the GlassFish Server. This
topic is discussed in Mapping Roles to Users and Groups.

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 on the GlassFish Server is discussed in Managing Users and Groups on the 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 24–6 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.

Figure 24–6 Mapping Roles to Users and Groups

What Is a Realm?

A realm is a security policy domain defined for a web or application
server. 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. For a web application,
a realm is a complete database of users and groups identified as valid users
of a web application or a set of web applications and controlled by the same
authentication policy.

The Java EE server authentication service can govern users in multiple
realms. The file, admin-realm, and certificate realms come preconfigured for the 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 on the GlassFish Server.

What Is a User?

A user is an individual or application program
identity that has been defined in the GlassFish Server. In a web application,
a user can have associated with that identify a set of roles that entitle
the user to access all resources protected by those roles. Users can be associated
with a group.

A Java 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 Java EE server authentication service has no knowledge of the
user name and password you provide when you log in to the operating system.
The Java 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 the GlassFish Server. A Java EE user of the file realm can belong to a group on the GlassFish Server. (A user in the certificate realm cannot.) A group on the 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 on the 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 the 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 Java EE platform:

Principal: 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.

Security policy domain, also known as security domain or realm:
A scope over which a common security policy is defined and enforced by the
security administrator of the security service.

Security attributes: 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.

Credential: An object that contains or references
security attributes used to authenticate a principal for Java EE services.
A principal acquires a credential upon authentication or from another principal
that allows its credential to be used.

Managing Users and Groups on the GlassFish Server

Follow these steps for managing users before you run the tutorial examples.

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, type the correct port number in place of 4848.

In the navigation tree, expand the Configuration 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.

The Edit Realm page opens.

Select the admin-realm to add users you want
to enable as system administrators of the GlassFish Server.

The Edit
Realm page opens.

You cannot add users to the certificate realm by
using the Administration Console. In the certificate realm, you
can add only certificates. For information on adding (importing) certificates
to the certificate realm, see Adding Users to the Certificate Realm.

On the Edit Realm page, click the Manage Users button.

The
File Users or Admin Users page opens.

On the File Users or Admin Users page, click New to add a new
user to the realm.

The New File Realm User page opens.

Type 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 the GlassFish Server and Administration Console after
you add a user to the Admin Realm.

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.

Adding Users to the Certificate Realm

In the certificate realm, user identity is set up in the GlassFish Server security context
and populated with user data obtained from cryptographically verified client
certificates. For step-by-step instructions for creating this type of certificate,
see Working with Digital Certificates.

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 24–6.

For Java 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:

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:

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 Java 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 Java 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 on the GlassFish Server. Under these circumstances, you can enable
a default principal-to-role mapping on the GlassFish Server by using the Administration Console.
The task To Set Up Your System for Running the Security Examples explains how to do this. All the tutorial security examples
use default principal-to-role mapping.

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 sun-web.xml file, which is the file used for web
applications:

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 on the 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 Socket 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.
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 the 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. Select Next to move through the series
of dialog boxes, and select Finish when you reach the last dialog box. The
certificates will display only the first time. When you accept the certificates,
subsequent hits to this site assume that you still trust the content.

Working with Digital Certificates

Digital certificates for the GlassFish Server have already been generated
and can be found in the directory as-install/domain-dir/config/.
These digital certificates are self-signed and are intended for use in a development
environment; they are not intended for production purposes. For production
purposes, generate your own certificates and have them signed by a CA.

To use SSL, an application or web server must have an associated certificate
for each external interface, or IP address, that accepts secure connections.
The theory behind this design is that a server should provide some kind of
reasonable assurance that its owner is who you think it is, particularly before
receiving any sensitive information. It may be useful to think of a certificate
as a “digital driver’s license” for an Internet address.
The certificate states with which company the site is associated, along with
some basic contact information about the site owner or administrator.

The
digital certificate is cryptographically signed by its owner and is difficult
for anyone else to forge. For sites involved in e-commerce or in any other
business transaction in which authentication of identity is important, a certificate
can be purchased from a well-known CA such as VeriSign or Thawte. If your
server certificate is self-signed, you must install it in the GlassFish Server keystore
file (keystore.jks). If your client certificate is self-signed,
you should install it in the GlassFish Server truststore file (cacerts.jks).

Sometimes, authentication is not really a concern. For example, an administrator
might simply want to ensure that data being transmitted and received by the
server is private and cannot be snooped by anyone eavesdropping on the connection.
In such cases, you can save the time and expense involved in obtaining a CA
certificate and simply use a self-signed certificate.

SSL uses public-key cryptography, which
is based on key pairs. Key pairs contain one public
key and one private key. Data encrypted with one key can be decrypted only
with the other key of the pair. This property is fundamental to establishing
trust and privacy in transactions. For example, using SSL, the server computes
a value and encrypts it by using its private key. The encrypted value is called
a digital signature. The client decrypts the encrypted
value by using the server’s public key and compares the value to its
own computed value. If the two values match, the client can trust that the
signature is authentic, because only the private key could have been used
to produce such a signature.

Digital certificates
are used with HTTPS to authenticate web clients. The HTTPS service of most
web servers will not run unless a digital certificate has been installed.
Use the procedure outlined in the next section, Creating a Server Certificate, to set up a digital certificate that can be
used by your application or web server to enable SSL.

One tool that can be used to set
up a digital certificate is keytool, a key and certificate
management utility that ships with the JDK. This tool enables users to administer
their own public/private key pairs and associated certificates for use in
self-authentication, whereby the user authenticates himself or herself to
other users or services, or data integrity and authentication services, using
digital signatures. The tool also allows users to cache the public keys, in
the form of certificates, of their communicating peers. For a better understanding
of keytool and public-key cryptography, see the keytool documentation at http://download.oracle.com/javase/6/docs/technotes/tools/solaris/keytool.html.

Creating a Server Certificate

A server certificate has already been created for the GlassFish Server and
can be found in the domain-dir/config/ directory. The
server certificate is in keystore.jks. The cacerts.jks file contains all the trusted certificates, including client certificates.

If necessary, you
can use keytool to generate certificates. The keytool utility stores the keys and certificates in a file termed a keystore, a repository of certificates used for identifying a
client or a server. Typically, a keystore is a file that contains one client’s
or one server’s identity. The keystore protects private keys by using
a password.

If you don’t specify a directory when specifying the keystore
file name, the keystores are created in the directory from which the keytool command is run. This can be the directory where the application
resides, or it can be a directory common to many applications.

The general steps for creating a server certificate are as follows.

Create the keystore.

Export the certificate from the keystore.

Sign the certificate.

Import
the certificate into a truststore: a repository of
certificates used for verifying the certificates. A truststore typically contains
more than one certificate.

To Use keytool to Create a Server
Certificate

Run keytool to generate a new key pair in the default
development keystore file, keystore.jks. This example
uses the alias server-alias to generate a new public/private
key pair and wrap the public key into a self-signed certificate inside keystore.jks. The key pair is generated by using an algorithm of
type RSA, with a default password of changeit. For more
information and other examples of creating and managing keystore files, read
the keytool online help at http://download.oracle.com/javase/6/docs/technotes/tools/solaris/keytool.html.

When you press Enter, keytool prompts you to enter
the server name, organizational unit, organization, locality, state, and country
code.

You must type the server name in response to keytool’s
first prompt, in which it asks for first and last names. For testing purposes,
this can be localhost.

When you run the example applications, the host (server name) specified
in the keystore must match the host identified in the javaee.server.name property specified in the file tut-install/examples/bp-project/build.properties.

Export the generated server certificate in keystore.jks into
the file server.cer.

Chapter 25 Getting Started
Securing Web Applications

A web application is accessed using a web browser over a network, such
as the Internet or a company’s intranet. As discussed in Distributed Multitiered Applications, the Java EE
platform uses a distributed multitiered application model, and web applications
run in the web tier.

Web applications contain resources that can be accessed by many users.
These resources often traverse unprotected, open networks, such as the Internet.
In such an environment, a substantial number of web applications will require
some type of security. The ways to implement security for Java EE web applications
are discussed in a general way in Securing Containers.
This chapter provides more detail and a few examples that explore these security
services as they relate to web components.

Overview of Web Application Security

In
the Java EE platform, web components provide the dynamic extension capabilities
for a web server. Web components can be Java servlets or JavaServer Faces
pages. The interaction between a web client and a web application is illustrated
in Figure 25–1.

Figure 25–1 Java Web Application Request Handling

Certain aspects of web application security can be configured when the
application is installed, or deployed, to the web container. Annotations and/or
deployment descriptors are used to relay information to the deployer about
security and other aspects of the application. Specifying this information
in annotations or in the deployment descriptor helps the deployer set up the
appropriate security policy for the web application. Any values explicitly
specified in the deployment descriptor override any values specified in annotations.

Security for Java EE web applications can be implemented in the following
ways.

Declarative security: Can be
implemented using either metadata annotations or an application’s deployment
descriptor. See Overview of Java EE Security for
more information.

Programmatic security: Is embedded in an application
and can be used to make security decisions when declarative security alone
is not sufficient to express the security model of an application. Declarative
security alone may not be sufficient when conditional login in a particular
work flow, instead of for all cases, is required in the middle of an application.
See Overview of Java EE Security for more
information.

Servlet 3.0 provides the authenticate, login, and logout methods of the HttpServletRequest interface. With the addition of the authenticate, login, and logout methods to the Servlet specification,
an application deployment descriptor is no longer required for web applications
but may still be used to further specify security requirements beyond the
basic default values.

Message Security: Works with web services and incorporates
security features, such as digital signatures and encryption, into the header
of a SOAP message, working in the application layer, ensuring end-to-end security.
Message security is not a component of Java EE 6 and is mentioned
here for informational purposes only.

Some of the material in this chapter builds on material presented earlier
in this tutorial. In particular, this chapter assumes that you are familiar
with the information in the following chapters:

Securing Web Applications

Web applications are created by application developers who give, sell,
or otherwise transfer the application to an application deployer for installation
into a runtime environment. Application developers communicate how to set
up security for the deployed application by using annotations or deployment
descriptors. This information is passed on to the deployer, who uses it to
define method permissions for security roles, set up user authentication,
and set up the appropriate transport mechanism. If the application developer
doesn’t define security requirements, the deployer will have to determine
the security requirements independently.

Some elements necessary for security in a web application cannot be
specified as annotations for all types of web applications. This chapter explains
how to secure web applications using annotations wherever possible. It explains
how to use deployment descriptors where annotations cannot be used.

Specifying Security Constraints

A security constraint is used to define the access
privileges to a collection of resources using their URL mapping.

If your web application uses a servlet,
you can express the security constraint information by using annotations.
Specifically, you use the @HttpConstraint and, optionally,
the @HttpMethodConstraint annotations within the @ServletSecurity annotation to specify a security constraint.

If your web application does not use a servlet, however, you must specify
a security-constraint element in the deployment descriptor
file. The authentication mechanism cannot be expressed using annotations,
so if you use any authentication method other than BASIC (the
default), a deployment descriptor is required.

The following subelements can be part of a security-constraint:

Web resource collection (web-resource-collection): A list of URL patterns (the part of a
URL after the host name and port you want to constrain)
and HTTP operations (the methods within the files that match the URL pattern
you want to constrain) that describe a set of resources to be protected. Web
resource collections are discussed in Specifying a Web Resource Collection.

User data constraint (user-data-constraint):
Specifies how data is protected when transported between a client and a server.
User data constraints are discussed in Specifying a Secure Connection.

Specifying a Web Resource Collection

A web resource collection consists of the following subelements:

web-resource-name is the name you use for
this resource. Its use is optional.

url-pattern is used to list the
request URI to be protected. Many applications have both unprotected and protected
resources. To provide unrestricted access to a resource, do not configure
a security constraint for that particular request URI.

The request URI is the part of a URL after the
host name and port. For example, let’s say that you have an e-commerce
site with a catalog that you would want anyone to be able to access and browse,
and a shopping cart area for customers only. You could set up the paths for
your web application so that the pattern /cart/* is protected
but nothing else is protected. Assuming that the application is installed
at context path /myapp, the following are true:

http://localhost:8080/myapp/index.xhtml is not protected.

http://localhost:8080/myapp/cart/index.xhtmlis protected.

A user will be prompted to log in the first time he or she accesses
a resource in the cart/ subdirectory.

http-method or http-method-omission is
used to specify which methods should be protected or which methods should
be omitted from protection. An HTTP method is protected by a web-resource-collection under any of the following circumstances:

If no HTTP methods are named in the collection (which means
that all are protected)

If the collection specifically names the HTTP method in an http-method subelement

If the collection contains one or more http-method-omission elements, none of which names the HTTP method

Specifying an Authorization Constraint

An authorization constraint (auth-constraint) contains
the role-name element. You can use as many role-name elements
as needed here.

An authorization constraint establishes a requirement for authentication
and names the roles authorized to access the URL patterns and HTTP methods
declared by this security constraint. If there is no authorization constraint,
the container must accept the request without requiring user authentication.
If there is an authorization constraint but no roles are specified within
it, the container will not allow access to constrained requests under any
circumstances. Each role name specified here must either correspond to the
role name of one of the security-role elements defined
for this web application or be the specially reserved role name *,
which indicates all roles in the web application. Role names are case sensitive.
The roles defined for the application must be mapped to users and groups defined
on the server, except when default principal-to-role mapping is used.

For a servlet, the @HttpConstraint and @HttpMethodConstraint annotations accept a rolesAllowed element that
specifies the authorized roles.

Specifying a Secure Connection

A user data constraint (user-data-constraint in the
deployment descriptor) contains the transport-guarantee subelement.
A user data constraint can be used to require that a protected transport-layer
connection, such as HTTPS, be used for all constrained URL patterns and HTTP
methods specified in the security constraint. The choices for transport guarantee
are CONFIDENTIAL, INTEGRAL, or NONE. If you specify CONFIDENTIAL or INTEGRAL as
a security constraint, it generally means that the use of SSL is required
and applies to all requests that match the URL patterns in the web resource
collection, not just to the login dialog box.

The strength of the required protection is defined by the value of the
transport guarantee.

Specify CONFIDENTIAL when the application
requires that data be transmitted so as to prevent other entities from observing
the contents of the transmission.

Specify INTEGRAL when the application requires
that the data be sent between client and server in such a way that it cannot
be changed in transit.

Specify NONE to indicate that the container
must accept the constrained requests on any connection, including an unprotected
one.

The user data constraint is handy to use in conjunction with basic and
form-based user authentication. When the login authentication method is set
to BASIC or FORM, passwords are not
protected, meaning that passwords sent between a client and a server on an
unprotected session can be viewed and intercepted by third parties. Using
a user data constraint with the user authentication mechanism can alleviate
this concern. Configuring a user authentication mechanism is described in Specifying an Authentication Mechanism in the Deployment Descriptor.

To guarantee that data is transported over a secure connection, ensure
that SSL support is configured for your server. SSL support is already configured
for the GlassFish Server.

Note –

After you switch to SSL for a session, you should never accept
any non-SSL requests for the rest of that session. For example, a shopping
site might not use SSL until the checkout page, and then it might switch to
using SSL to accept your card number. After switching to SSL, you should stop
listening to non-SSL requests for this session. The reason for this practice
is that the session ID itself was not encrypted on the earlier communications.
This is not so bad when you’re only doing your shopping, but after the
credit card information is stored in the session, you don’t want anyone
to use that information to fake the purchase transaction against your credit
card. This practice could be easily implemented by using a filter.

Specifying Separate Security Constraints for Various
Resources

You can create a separate security constraint for various resources
within your application. For example, you could allow users with the role
of PARTNER access to the GET and POST methods of all resources with the URL pattern /acme/wholesale/* and allow users with the role of CLIENT access
to the GET and POST methods of all resources
with the URL pattern /acme/retail/*. An example of a deployment
descriptor that would demonstrate this functionality is the following:

When the same url-pattern and http-method occur
in multiple security constraints, the constraints on the pattern and method
are defined by combining the individual constraints, which could result in
unintentional denial of access.

Specifying Authentication Mechanisms

A user authentication mechanism specifies

The way a user gains access to web content

With basic authentication, the realm in which the user will
be authenticated

With form-based authentication, additional attributes

When an authentication mechanism is specified, the user must be authenticated
before access is granted to any resource that is constrained by a security
constraint. There can be multiple security constraints applying to multiple
resources, but the same authentication method will apply to all constrained
resources in an application.

Before you can authenticate a user, you must have a database of user
names, passwords, and roles configured on your web or application server.
For information on setting up the user database, see Managing Users and Groups on the GlassFish Server.

HTTP basic authentication and form-based authentication are not very
secure authentication mechanisms. Basic authentication sends user names and
passwords over the Internet as Base64-encoded text; form-based authentication
sends this data as plain text. In both cases, the target server is not authenticated.
Therefore, these forms of authentication leave user data exposed and vulnerable.
If someone can intercept the transmission, the user name and password information
can easily be decoded. However, when a secure transport mechanism, such as
SSL, or security at the network level, such as the Internet Protocol Security
(IPsec) protocol or virtual private network (VPN) strategies, is used in conjunction
with basic or form-based authentication, some of these concerns can be alleviated.
To specify a secure transport mechanism, use the elements described in Specifying a Secure Connection.

HTTP Basic Authentication

Specifying HTTP basic authentication requires
that the server request a user name and password from the web client and verify
that the user name and password are valid by comparing them against a database
of authorized users in the specified or default realm.

Basic authentication is the default when you do not specify an authentication
mechanism.

When basic authentication is used, the following actions occur:

A client requests access to a protected resource.

The web server returns a dialog box that requests the user
name and password.

The client submits the user name and password to the server.

The server authenticates the user in the specified realm and,
if successful, returns the requested resource.

Figure 25–2 HTTP Basic Authentication

Form-Based Authentication

Form-based authentication allows the developer
to control the look and feel of the login authentication screens by customizing
the login screen and error pages that an HTTP browser presents to the end
user. When form-based authentication is declared, the following actions occur.

A client requests access to a protected resource.

If the client is unauthenticated, the server redirects the
client to a login page.

The client submits the login form to the server.

The server attempts to authenticate the user.

If authentication succeeds, the authenticated user’s
principal is checked to ensure that it is in a role that is authorized to
access the resource. If the user is authorized, the server redirects the client
to the resource by using the stored URL path.

If authentication fails, the client is forwarded or redirected
to an error page.

Figure 25–3 shows what happens
when you specify form-based authentication.

Figure 25–3 Form-Based Authentication

When you create a form-based login, be sure to maintain sessions using
cookies or SSL session information.

For authentication to proceed appropriately, the action of the login
form must always be j_security_check. This restriction
is made so that the login form will work no matter which resource it is for
and to avoid requiring the server to specify the action field of the outbound
form. The following code snippet shows how the form should be coded into the
HTML page:

Digest Authentication

Like basic authentication, digest authentication authenticates
a user based on a user name and a password. However, unlike basic authentication,
digest authentication does not send user passwords over the network. Instead,
the client sends a one-way cryptographic hash of the password and additional
data. Although passwords are not sent on the wire, digest authentication requires
that clear-text password equivalents be available to the authenticating container
so that it can validate received authenticators by calculating the expected
digest.

Client Authentication

With client authentication, the web server authenticates
the client by using the client’s public key certificate. Client authentication
is a more secure method of authentication than either basic or form-based
authentication. It uses HTTP over SSL (HTTPS), in which the server authenticates
the client using the client’s public key certificate. SSL technology
provides data encryption, server authentication, message integrity, and optional
client authentication for a TCP/IP connection. You can think of a public key
certificate as the digital equivalent of a passport. The certificate is issued
by a trusted organization, a certificate authority (CA), and provides identification
for the bearer.

Before using client authentication, make sure the client has a valid
public key certificate. For more information on creating and using public
key certificates, read Working with Digital Certificates.

Mutual Authentication

With mutual authentication, the server and the
client authenticate each other. Mutual authentication is of two types:

When you try to access a web resource that is constrained by a security-constraint element, the web container activates the authentication mechanism
that has been configured for that resource. The authentication mechanism specifies
how the user will be prompted to log in. If the login-config element
is present and the auth-method element contains a value
other than NONE, the user must be authenticated to access
the resource. If you do not specify an authentication mechanism, authentication
of the user is not required.

The following example shows how to declare form-based authentication
in your deployment descriptor:

The following example shows how to declare digest authentication in
your deployment descriptor:

<login-config>
<auth-method>DIGEST</auth-method>
</login-config>

The following example shows how to declare client authentication in
your deployment descriptor:

<login-config>
<auth-method>CLIENT-CERT</auth-method>
</login-config>

Declaring Security Roles

You can declare security role names used in web applications by using
the security-role element of the deployment descriptor.
Use this element to list all the security roles that you have referenced in
your application.

The following snippet of a deployment descriptor declares the roles
that will be used in an application using the security-role element
and specifies which of these roles is authorized to access protected resources
using the auth-constraint element:

In this example, the security-role element lists
all the security roles used in the application: manager and employee. This enables the deployer to map all the roles defined
in the application to users and groups defined on the GlassFish Server.

The auth-constraint element specifies the role, manager, that can access the HTTP methods PUT, DELETE, GET, POST located
in the directory specified by the url-pattern element (/jsp/security/protected/*).

The @ServletSecurity annotation cannot be used in
this situation because its constraints apply to all URL patterns specified
by the @WebServlet annotation.

Using Programmatic Security with Web Applications

Programmatic security is used by security-aware applications when declarative
security alone is not sufficient to express the security model of the application.

Authenticating Users Programmatically

Servlet 3.0 specifies the following methods of the HttpServletRequest interface that enable you to authenticate users for a web
application programmatically:

authenticate, which allows an application
to instigate authentication of the request caller by the container from within
an unconstrained request context. A login dialog box displays and collects
the user name and password for authentication purposes.

login, which allows an application
to collect username and password information as an alternative to specifying
form-based authentication in an application deployment descriptor.

logout, which allows an application
to reset the caller identity of a request.

The following example code shows how to use the login and logout methods:

Checking Caller Identity Programmatically

In general, security management should be enforced by the container
in a manner that is transparent to the web component. The security API described
in this section should be used only in the less frequent situations in which
the web component methods need to access the security context information.

Servlet 3.0 specifies the following methods that enable you to access
security information about the component’s caller:

getRemoteUser, which determines the
user name with which the client authenticated. The getRemoteUser method
returns the name of the remote user (the caller) associated by the container
with the request. If no user has been authenticated, this method returns null.

isUserInRole, which determines whether
a remote user is in a specific security role. If no user has been authenticated,
this method returns false. This method expects a String user role-name parameter.

The security-role-ref element should be declared in the deployment descriptor
with a role-name subelement containing the role name to
be passed to the method. Using security role references is discussed in Declaring and Linking Role References.

getUserPrincipal, which determines
the principal name of the current user and returns a java.security.Principal object. If no user has been authenticated, this method returns null. Calling the getName method on the Principal returned by getUserPrincipal returns
the name of the remote user.

Your application can make business-logic decisions based on the information
obtained using these APIs.

Example Code for Programmatic Security

The following code demonstrates the use of programmatic security for
the purposes of programmatic login. This servlet does the following:

It displays information about the current user.

It prompts the user to log in.

It prints out the information again to demonstrate the effect
of the login method.

It logs the user out.

It prints out the information again to demonstrate the effect
of the logout method.

Declaring and Linking Role References

A security role reference defines a mapping between
the name of a role that is called from a web component using isUserInRole(String
role) and the name of a security role that has been defined for
the application. If no security-role-ref element is declared
in a deployment descriptor and the isUserInRole method
is called, the container defaults to checking the provided role name against
the list of all security roles defined for the web application. Using the
default method instead of using the security-role-ref element
limits your flexibility to change role names in an application without also
recompiling the servlet making the call.

The security-role-ref element is used when an application
uses the HttpServletRequest.isUserInRole(String role).
The value passed to the isUserInRole method is a String representing the role name of the user. The value of the role-name element must be the String used
as the parameter to the HttpServletRequest.isUserInRole(String
role). The role-link must contain the name
of one of the security roles defined in the security-role elements.
The container uses the mapping of security-role-ref to security-role when determining the return value of the call.

For example, to map the security role reference cust to
the security role with role name bankCustomer, the syntax
would be:

If the servlet method is called by a user in the bankCustomer security
role, isUserInRole("cust") returns true.

The role-link element in the security-role-ref element
must match a role-name defined in the security-role element
of the same web.xml deployment descriptor, as shown here:

<security-role>
<role-name>bankCustomer</role-name>
</security-role>

A security role reference, including the name defined by the reference,
is scoped to the component whose deployment descriptor contains the security-role-ref deployment descriptor element.

Examples: Securing Web Applications

Some basic setup is required before any of the example applications
will run correctly. The examples use annotations, programmatic security, and/or
declarative security to demonstrate adding security to existing web applications.

Here are some other locations where you will find examples of securing
various types of applications:

Be sure to write down the user name and password for the user you create
so that you can use it for testing the example applications. Authentication
is case sensitive for both the user name and password, so write down the user
name and password exactly. This topic is discussed more in Managing Users and Groups on the GlassFish Server.

Set up Default Principal to Role Mapping on the GlassFish Server:

From the Administration Console, expand the Configuration node.

Select the Security node.

Select the Default Principal to Role Mapping Enabled check box.

Click Save.

Example: Basic Authentication with a Servlet

This example explains how to use basic authentication with a servlet.
With basic authentication of a servlet, the web browser presents a standard
login dialog that is not customizable. When a user submits his or her name
and password, the server determines whether the user name and password are
those of an authorized user and sends the requested web resource if the user
is authorized to view it.

In general, the following steps are necessary for adding basic authentication
to an unsecured servlet, such as the ones described in Chapter 3, Getting Started with Web Applications. In the example application
included with this tutorial, many of these steps have been completed for you
and are listed here simply to show what needs to be done should you wish to
create a similar application. The completed version of this example application
can be found in the directory tut-install/examples/security/hello2_basicauth/.

Specifying Security for Basic Authentication Using
Annotations

The default authentication mechanism used by the GlassFish Server is basic
authentication. With basic authentication, the GlassFish Server spawns a standard
login dialog to collect user name and password data for a protected resource.
Once the user is authenticated, access to the protected resource is permitted.

To specify security for a servlet,
use the @ServletSecurity annotation. This annotation allows
you to specify both specific constraints on HTTP methods and more general
constraints that apply to all HTTP methods for which no specific constraint
is specified. Within the @ServletSecurity annotation, you
can specify the following annotations:

The @HttpMethodConstraint annotation,
which applies to a specific HTTP method

The more general @HttpConstraint annotation,
which applies to all HTTP methods for which there is no corresponding @HttpMethodConstraint annotation

Both the @HttpMethodConstraint and @HttpConstraint annotations within the @ServletSecurity annotation
can specify the following:

A transportGuarantee element that specifies
the data protection requirements (that is, whether or not SSL/TLS is required)
that must be satisfied by the connections on which requests arrive. Valid
values for this element are NONE and CONFIDENTIAL.

A rolesAllowed element that specifies the
names of the authorized roles.

For the hello2_basicauth application, the GreetingServlet has the following annotations:

These annotations specify that the request URI /greeting can
be accessed only by users who have been authorized to access this URL because
they have been verified to be in the role TutorialUser.
The data will be sent over a protected transport in order to keep the user
name and password data from being read in transit.

To Build, Package, and Deploy the Servlet Basic Authentication
Example Using NetBeans IDE

To Build, Package, and Deploy the Servlet Basic Authentication
Example Using Ant

This command calls the default target, which builds
and packages the application into a WAR file, hello2_basicauth.war,
that is located in the dist directory.

Make sure that the GlassFish Server is started.

To deploy the application, type the following command:

ant deploy

To Run the Basic Authentication Servlet

In a web browser, navigate to the following URL:

https://localhost:8181/hello2_basicauth/greeting

You may be prompted to accept the security certificate for the server.
If so, accept the security certificate. If the browser warns that the certificate
is invalid because it is self-signed, add a security exception for the application.

An Authentication Required dialog box appears. Its appearance varies,
depending on the browser you use. Figure 25–6 shows an example.

Figure 25–6 Sample Basic Authentication Dialog Box

Type a user name and password combination that corresponds to
a user who has already been created in the file realm of
the GlassFish Server and has been assigned to the group of TutorialUser;
then click OK.

Basic authentication is case sensitive for both
the user name and password, so type the user name and password exactly as
defined for the GlassFish Server.

The server returns the requested resource if all the following conditions
are met.

A user with the user name you entered is defined for the GlassFish Server.

The user with the user name you entered has the password you
entered.

The user name and password combination you entered is assigned
to the group TutorialUser on the GlassFish Server.

The role of TutorialUser, as defined for
the application, is mapped to the group TutorialUser, as
defined for the GlassFish Server.

When these conditions are met and the server has authenticated the user,
the application will appear as shown in Figure 3–2 but with a different URL.

Type a name in the text field and click the Submit button.

Because you have already been authorized, the name you enter in this
step does not have any limitations. You have unlimited access to the application
now.

The application responds by saying “Hello” to you, as shown
in Figure 3–3 but with a different
URL.

Next Steps

For repetitive testing of this example, you may need to close and reopen
your browser. You should also run the ant undeploy and ant clean targets or the NetBeans IDE Clean and Build option
to get a fresh start.

This example explains how to use form-based authentication with a JavaServer
Faces application. With form-based authentication, you can customize the login
screen and error pages that are presented to the web client for authentication
of the user name and password. When a user submits his or her name and password,
the server determines whether the user name and password are those of an authorized
user and, if authorized, sends the requested web resource.

The completed version of this example application can be found in the
directory tut-install/examples/security/hello1_formauth/.

Creating the Login Form and the Error Page

When using form-based login mechanisms, you must specify a page that
contains the form you want to use to obtain the user name and password, as
well as a page to display if login authentication fails. This section discusses
the login form and the error page used in this example. Specifying Security for the Form-Based Authentication Example shows
how you specify these pages in the deployment descriptor.

The login page can be an HTML page, a JavaServer Faces or JSP page,
or a servlet, and it must return an HTML page containing a form that conforms
to specific naming conventions (see the Java Servlet 3.0 specification for
more information on these requirements). To do this, include the elements
that accept user name and password information between <form></form> tags in your login page. The content of an HTML page, JavaServer
Faces or JSP page, or servlet for a login page should be coded as follows:

The full code for the login page used in this example can be found at tut-install/examples/security/hello1_formauth/web/login.xhtml. An example of the running login form page is shown later, in Figure 25–7. Here is the code for this
page:

The login error page is displayed if the user enters a user name and
password combination that is not authorized to access the protected URI. For
this example, the login error page can be found at tut-install/examples/security/hello1_formauth/web/error.xhtml. For this example, the login error page explains the reason for
receiving the error page and provides a link that will allow the user to try
again. Here is the code for this page:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Login Error</title>
</h:head>
<h:body>
<h2>Invalid user name or password.</h2>
<p>Please enter a user name or password that is authorized to access this
application. For this application, this means a user that has been
created in the <code>file</code> realm and has been assigned to the
<em>group</em> of <code>TutorialUser</code>.</p>
<h:link outcome="login">Return to login page</h:link>
</h:body>
</html>

Specifying Security for the Form-Based Authentication
Example

This example takes a very simple servlet-based web application and adds
form-based security. To specify form-based instead of basic authentication
for a JavaServer Faces example, you must use the deployment descriptor.

The following sample code shows the security elements added to the deployment
descriptor for this example, which can be found in tut-install/examples/security/hello1_formauth/web/WEB-INF/web.xml.

This target will spawn any necessary compilations, copy files to the tut-install/examples/security/hello2_formauth/build/ directory, create the WAR file, and copy it to the tut-install/examples/security/hello2_formauth/dist/ directory.

To deploy hello2_formauth.war to the GlassFish Server,
type the following command:

Figure 25–7 Form-Based Login Page

Type a user name and password combination that corresponds to
a user who has already been created in the file realm of
the GlassFish Server and has been assigned to the group of TutorialUser.

Form-based authentication is case sensitive for both the user
name and password, so type the user name and password exactly as defined for
the GlassFish Server.

Click the Submit button.

If you entered My_Name as the name and My_Pwd for
the password, the server returns the requested resource if all the following
conditions are met.

A user with the user name My_Name is defined
for the GlassFish Server.

The user with the user name My_Name has
a password My_Pwd defined for the GlassFish Server.

The user My_Name with the password My_Pwd is assigned to the group TutorialUser on the GlassFish Server.

The role TutorialUser, as defined for the
application, is mapped to the group TutorialUser, as defined
for the GlassFish Server.

When these conditions are met and the server
has authenticated the user, the application appears.

Type your name and click the Submit button.

Because
you have already been authorized, the name you enter in this step does not
have any limitations. You have unlimited access to the application now.

The application responds by saying “Hello” to you.

Next Steps

For additional testing and to see the login error page generated, close
and reopen your browser, type the application URL, and type a user name and
password that are not authorized.

Note –

For repetitive testing of this example, you may need to close
and reopen your browser. You should also run the ant clean and
ant undeploy commands to ensure a fresh build if using
the Ant tool, or select Clean and Build then Deploy if using NetBeans IDE.

Chapter 26 Getting Started
Securing Enterprise Applications

The following parties are responsible for administering security for
enterprise applications:

System administrator: Responsible
for setting up a database of users and assigning them to the proper group.
The system administrator is also responsible for setting GlassFish Serverproperties
that enable the applications to run properly. Some security-related examples
set up a default principal-to-role mapping, anonymous users, default users,
and propagated identities. When needed for this tutorial, the steps for performing
specific tasks are provided.

Application developer/bean provider:
Responsible for annotating the classes and methods of the enterprise application
in order to provide information to the deployer about which methods need to
have restricted access. This tutorial describes the steps necessary to complete
this task.

Deployer: Responsible for
taking the security view provided by the application developer and implementing
that security upon deployment. This document provides the information needed
to accomplish this task for the tutorial example applications.

Securing Enterprise Beans

Enterprise beans are Java EE components that implement EJB technology.
Enterprise beans run in the EJB container, a runtime environment within the GlassFish Server.
Although transparent to the application developer, the EJB container provides
system-level services, such as transactions and security to its enterprise
beans, which form the core of transactional Java EE applications.

Enterprise bean methods can be secured in either of the following ways:

Declarative security (preferred):
Expresses an application component’s security requirements using either
deployment descriptors or annotations. The presence of an annotation in the
business method of an enterprise bean class that specifies method permissions
is all that is needed for method protection and authentication in some situations.
This section discusses this simple and efficient method of securing enterprise
beans.

Because of some limitations to the simplified method of
securing enterprise beans, you would want to continue to use the deployment
descriptor to specify security information in some instances. An authentication
mechanism must be configured on the server for the simple solution to work.
Basic authentication is the GlassFish Server’s default authentication method.

This tutorial explains how to invoke user name/password authentication
of authorized users by decorating the enterprise application’s business
methods with annotations that specify method permissions.

To make the deployer’s task easier, the application developer
can define security roles. A security role is a grouping of permissions that
a given type of application users must have in order to successfully use the
application. For example, in a payroll application, some users will want to
view their own payroll information (employee), some
will need to view others’ payroll information (manager),
and some will need to be able to change others’ payroll information
(payrollDept). The application developer would determine
the potential users of the application and which methods would be accessible
to which users. The application developer would then decorate classes or methods
of the enterprise bean with annotations that specify the types of users authorized
to access those methods. Using annotations to specify authorized users is
described in Specifying Authorized Users by Declaring Security Roles.

When one of the annotations is used to define method permissions, the
deployment system will automatically require user name/password authentication.
In this type of authentication, a user is prompted to enter a user name and
password, which will be compared against a database of known users. If the
user is found and the password matches, the roles that the user is assigned
will be compared against the roles that are authorized to access the method.
If the user is authenticated and found to have a role that is authorized to
access that method, the data will be returned to the user.

Programmatic security: For an enterprise bean, code
embedded in a business method that is used to access a caller’s identity
programmatically and that uses this information to make security decisions.
Programmatic security is useful when declarative security alone is not sufficient
to express the security model of an application.

In general, security
management should be enforced by the container in a manner that is transparent
to the enterprise beans’ business methods. The programmatic security
APIs described in this chapter should be used only in the less frequent situations
in which the enterprise bean business methods need to access the security-context
information, such as when you want to grant access based on the time of day
or other nontrivial condition checks for a particular role.

As mentioned earlier, enterprise beans run in the EJB container, a runtime
environment within the GlassFish Server, as shown in Figure 26–1.

Figure 26–1 Java EE Server and Containers

This section discusses securing a Java EE application where one or more
modules, such as EJB JAR files, are packaged into an EAR file, the archive
file that holds the application. Security annotations will be used in the
Java programming class files to specify authorized users and basic, or user
name/password, authentication.

Enterprise beans often provide the business logic of a web application.
In these cases, packaging the enterprise bean within the web application’s
WAR module simplifies deployment and application organization. Enterprise
beans may be packaged within a WAR module as Java class files or within a
JAR file that is bundled within the WAR module. When a servlet or JavaServer
Faces page handles the web front end and the application is packaged into
a WAR module as a Java class file, security for the application can be handled
in the application’s web.xml file. The EJB in the
WAR file can have its own deployment descriptor, ejb-jar.xml,
if required. Securing web applications using web.xml is
discussed in Chapter 25, Getting Started Securing Web Applications.

The following sections describe declarative and programmatic security
mechanisms that can be used to protect enterprise bean resources. The protected
resources include enterprise bean methods that are called from application
clients, web components, or other enterprise beans.

For more information on this topic, read the Enterprise JavaBeans 3.1
specification. This document can be downloaded from http://jcp.org/en/jsr/detail?id=318. Chapter 17
of this specification, “Security Management,” discusses security
management for enterprise beans.

Securing an Enterprise Bean Using Declarative Security

Declarative security enables the application developer to specify which
users are authorized to access which methods of the enterprise beans and to
authenticate these users with basic, or username-password, authentication.
Frequently, the person who is developing an enterprise application is not
the same person who is responsible for deploying the application. An application
developer who uses declarative security to define method permissions and authentications
mechanisms is passing along to the deployer a security view of
the enterprise beans contained in the EJB JAR. When a security view is passed
on to the deployer, he or she uses this information to define method permissions
for security roles. If you don’t define a security view, the deployer
will have to determine what each business method does to determine which users
are authorized to call each method.

A security view consists
of a set of security roles, a semantic grouping of permissions that a given
type of users of an application must have to successfully access the application.
Security roles are meant to be logical roles, representing a type of user.
You can define method permissions for each security role. A method permission
is a permission to invoke a specified group of methods of an enterprise bean’s
business interface, home interface, component interface, and/or web service
endpoints. After method permissions are defined, user name/password authentication
will be used to verify the identity of the user.

It is important to keep in mind that security roles are used to define
the logical security view of an application. They should not be confused with
the user groups, users, principals, and other concepts that exist in the GlassFish Server.
An additional step is required to map the roles defined in the application
to users, groups, and principals that are the components of the user database
in the file realm of the GlassFish Server. These steps are outlined in Mapping Roles to Users and Groups.

The following sections show how an application developer uses declarative
security to either secure an application or to create a security view to pass
along to the deployer.

Specifying Authorized Users by Declaring Security
Roles

This section discusses how to use annotations to specify the method
permissions for the methods of a bean class. For more information on these
annotations, refer to the Common Annotations for the Java Platform specification
at http://jcp.org/en/jsr/detail?id=250.

Method permissions can be specified on the class, the business methods
of the class, or both. Method permissions can be specified on a method of
the bean class to override the method permissions value specified on the entire
bean class. The following annotations are used to specify method permissions:

@DeclareRoles: Specifies all the roles that
the application will use, including roles not specifically named in a @RolesAllowed annotation. The set of security roles the application uses is the
total of the security roles defined in the @DeclareRoles and @RolesAllowed annotations.

The @DeclareRoles annotation
is specified on a bean class, where it serves to declare roles that can be
tested (for example, by calling isCallerInRole) from
within the methods of the annotated class. When declaring the name of a role
used as a parameter to the isCallerInRole(String roleName) method,
the declared name must be the same as the parameter value.

The following example code demonstrates the use of the @DeclareRoles annotation:

@DeclareRoles("BusinessAdmin")
public class Calculator {
...
}

The syntax for declaring more than one role is as shown in the following
example:

@DeclareRoles({"Administrator", "Manager", "Employee"})

@RolesAllowed("list-of-roles"): Specifies the security roles permitted to access methods in
an application. This annotation can be specified on a class or on one or more
methods. When specified at the class level, the annotation applies to all
methods in the class. When specified on a method, the annotation applies to
that method only and overrides any values specified at the class level.

To specify that no roles are authorized to access methods in an application,
use the @DenyAll annotation. To specify that a user in
any role is authorized to access the application, use the @PermitAll annotation.

When used in conjunction with the @DeclareRoles annotation,
the combined set of security roles is used by the application.

The following example code demonstrates the use of the @RolesAllowed annotation:

@PermitAll: Specifies that all security
roles are permitted to execute the specified method or methods. The user is
not checked against a database to ensure that he or she is authorized to access
this application.

This annotation can be specified on a class
or on one or more methods. Specifying this annotation on the class means that
it applies to all methods of the class. Specifying it at the method level
means that it applies to only that method.

The following example code demonstrates the use of the @PermitAll annotation:

The following code snippet demonstrates the use of the @DeclareRoles annotation with the isCallerInRole method.
In this example, the @DeclareRoles annotation declares
a role that the enterprise bean PayrollBean uses to
make the security check by using isCallerInRole("payroll") to
verify that the caller is authorized to change salary data:

In this example, assuming that aMethod, bMethod, and cMethod are methods of business interface A, the method permissions values of methods aMethod and bMethod are @RolesAllowed("HR") and @RolesAllowed("admin"), respectively. The method permissions for method cMethod have
not been specified.

To clarify, the annotations are not inherited by the subclass itself.
Instead, the annotations apply to methods of the superclass that are inherited
by the subclass.

Specifying an Authentication Mechanism and Secure
Connection

When method permissions are specified, basic user name/password authentication
will be invoked by the GlassFish Server.

To use a different type of authentication or to require a secure connection
using SSL, specify this information in an application deployment descriptor.

Securing an Enterprise Bean Programmatically

Programmatic security, code that is embedded in a business method, is
used to access a caller’s identity programmatically and uses this information
to make security decisions within the method itself.

Accessing an Enterprise Bean Caller’s Security
Context

In general, security management should be enforced by the container
in a manner that is transparent to the enterprise bean’s business methods.
The security API described in this section should be used only in the less
frequent situations in which the enterprise bean business methods need to
access the security context information, such as when you want to restrict
access to a particular time of day.

The javax.ejb.EJBContext interface provides two methods
that allow the bean provider to access security information about the enterprise
bean’s caller:

getCallerPrincipal, which allows
the enterprise bean methods to obtain the current caller principal’s
name. The methods might, for example, use the name as a key to information
in a database.

The following code sample illustrates the use of
the getCallerPrincipal method:

In this example, the enterprise bean obtains the principal name of the
current caller and uses it as the primary key to locate an EmployeeRecord entity. This example assumes that application has been deployed
such that the current caller principal contains the primary key used for the
identification of employees (for example, employee number).

isCallerInRole, which the enterprise
bean code can use to allow the bean provider/application developer to code
the security checks that cannot be easily defined using method permissions.
Such a check might impose a role-based limit on a request, or it might depend
on information stored in the database.

The enterprise bean code
can use the isCallerInRole method to test whether
the current caller has been assigned to a given security role. Security roles
are defined by the bean provider or the application assembler and are assigned
by the deployer to principals or principal groups that exist in the operational
environment.

The following code sample illustrates the use of the isCallerInRole method:

You would use programmatic security in this way to dynamically control
access to a method, for example, when you want to deny access except during
a particular time of day. An example application that uses the getCallerPrincipal and isCallerInRole methods is described
in Example: Securing an Enterprise Bean with Programmatic Security.

Propagating a Security Identity (Run-As)

You can specify whether a caller’s security identity should be
used for the execution of specified methods of an enterprise bean or whether
a specific run-as identity should be used. Figure 26–2 illustrates this concept.

Figure 26–2 Security Identity Propagation

In this illustration, an application client is making a call to an enterprise
bean method in one EJB container. This enterprise bean method, in turn, makes
a call to an enterprise bean method in another container. The security identity
during the first call is the identity of the caller. The security identity
during the second call can be any of the following options.

By default, the identity of the caller of the intermediate
component is propagated to the target enterprise bean. This technique is used
when the target container trusts the intermediate container.

A specific identity is
propagated to the target enterprise bean. This technique is used when the
target container expects access using a specific identity.

To
propagate an identity to the target enterprise bean, configure a run-as identity
for the bean, as described in Configuring a Component’s Propagated Security Identity. Establishing a run-as identity for an
enterprise bean does not affect the identities of its callers, which are the
identities tested for permission to access the methods of the enterprise bean.
The run-as identity establishes the identity that the enterprise bean will
use when it makes calls.

The run-as identity applies to the enterprise bean as a whole, including
all the methods of the enterprise bean’s business interface, local and
remote interfaces, component interface, and web service endpoint interfaces,
the message listener methods of a message-driven bean, the timeout method
of an enterprise bean, and all internal methods of the bean that might be
called in turn.

Configuring a Component’s Propagated Security
Identity

You can configure an enterprise bean’s run-as, or propagated,
security identity by using the @RunAs annotation, which
defines the role of the application during execution in a Java EE container.
The annotation can be specified on a class, allowing developers to execute
an application under a particular role. The role must map to the user/group
information in the container’s security realm. The @RunAs annotation
specifies the name of a security role as its parameter.

Here is some example code that demonstrates the use of the @RunAs annotation.

@RunAs("Admin")
public class Calculator {
//....
}

You will have to map the run-as role name to a given principal defined
on the GlassFish Server if the given roles are associated with more than one
user principal.

Trust between Containers

When an enterprise bean is designed so that either the original caller
identity or a designated identity is used to call a target bean, the target
bean will receive the propagated identity only. The target bean will not receive
any authentication data.

There is no way for the target container to authenticate the propagated
security identity. However, because the security identity is used in authorization
checks (for example, method permissions or with the isCallerInRole method),
it is vitally important that the security identity be authentic. Because no
authentication data is available to authenticate the propagated identity,
the target must trust that the calling container has propagated an authenticated
security identity.

By default, the GlassFish Server is configured to trust identities that
are propagated from different containers. Therefore, you do not need to take
any special steps to set up a trust relationship.

Deploying Secure Enterprise Beans

The deployer is responsible for ensuring that an assembled application
is secure after it has been deployed in the target operational environment.
If a security view has been provided to the deployer through the use of security
annotations and/or a deployment descriptor, the security view is mapped to
the mechanisms and policies used by the security domain in the target operational
environment, which in this case is the GlassFish Server. If no security view
is provided, the deployer must set up the appropriate security policy for
the enterprise bean application.

Deployment information is specific to a web or application server.

Examples: Securing Enterprise Beans

The following examples show how to secure enterprise beans using declarative
and programmatic security.

Example: Securing an Enterprise Bean with Declarative
Security

This section discusses how to configure an enterprise bean for basic
user name/password authentication. When a bean that is constrained in this
way is requested, the server requests a user name and password from the client
and verifies that the user name and password are valid by comparing them against
a database of authorized users on the GlassFish Server.

This example demonstrates security by starting with the unsecured enterprise
bean application, cart, which is found in the directory tut-install/examples/ejb/cart/ and is discussed in The cart Example.

In general, the following steps are necessary to add user name/password
authentication to an existing application that contains an enterprise bean.
In the example application included with this tutorial, these steps have been
completed for you and are listed here simply to show what needs to be done
should you wish to create a similar application.

Create an application like the one in The cart Example. The example in this tutorial starts with this example
and demonstrates adding basic authentication of the client to this application.
The example application discussed in this section can be found at tut-install/examples/security/cart-secure/.

The @RolesAllowed annotation is specified on methods
for which you want to restrict access. In this example, only users in the
role of TutorialUser will be allowed to add and remove
books from the cart and to list the contents of the cart. A @RolesAllowed annotation implicitly declares a role that will be referenced in
the application; therefore, no @DeclareRoles annotation
is required. The presence of the @RolesAllowed annotation
also implicitly declares that authentication will be required for a user to
access these methods. If no authentication method is specified in the deployment
descriptor, the type of authentication will be user name/password authentication.

To Build, Package, Deploy, and Run the Secure Cart
Example Using NetBeans IDE

Select the Open as Main Project and Open Required Projects check
boxes.

Click Open Project.

In the Projects tab, right-click the cart-secure project
and select Build.

In the Projects tab, right-click the cart-secure project
and select Deploy.

This step builds and packages the application
into cart-secure.ear, located in the directory tut-install/examples/security/cart-secure/dist/, and deploys this EAR file to your GlassFish Server instance.

To run the application client, right-click the cart-secure project
and select Run.

A Login for user: dialog box
appears.

In the dialog box, type the user name and password of a file realm
user created on the GlassFish Server and assigned to the group TutorialUser; then click OK.

If the user name and password you enter
are authenticated, the output of the application client appears in the Output
pane:

...
Retrieving book title from cart: Infinite Jest
Retrieving book title from cart: Bel Canto
Retrieving book title from cart: Kafka on the Shore
Removing "Gravity's Rainbow" from cart.
Caught a BookException: "Gravity's Rainbow" not in cart.
Java Result: 1
...

If the user name and password are not authenticated, the dialog box
reappears until you type correct values.

To Build, Package, Deploy, and Run the Secure Cart
Example Using Ant

To build the application and package it into an EAR file, type
the following command at the terminal window or command prompt:

ant

To deploy the application to the GlassFish Server, type the following
command:

ant deploy

To run the application client, type the following command:

ant run

This task retrieves the application client JAR and runs the application
client.

A Login for user: dialog box appears.

In the dialog box, type the user name and password of a file realm
user created on the GlassFish Server and assigned to the group TutorialUser; then click OK.

If the user name and password are authenticated,
the client displays the following output:

[echo] running application client container.
[exec] Retrieving book title from cart: Infinite Jest
[exec] Retrieving book title from cart: Bel Canto
[exec] Retrieving book title from cart: Kafka on the Shore
[exec] Removing "Gravity's Rainbow" from cart.
[exec] Caught a BookException: "Gravity's Rainbow" not in cart.
[exec] Result: 1

If the username and password are not authenticated, the dialog box reappears
until you type correct values.

Example: Securing an Enterprise Bean with Programmatic
Security

This example demonstrates how to use the getCallerPrincipal and isCallerInRole methods with an enterprise bean. This example
starts with a very simple EJB application, converter, and
modifies the methods of the ConverterBean so that currency
conversion will occur only when the requester is in the role of TutorialUser.

The completed version of this example can be found in the directory tut-install/examples/security/converter-secure. This example is based on the unsecured enterprise bean application, converter, which is discussed in Chapter 15, Getting Started with Enterprise Beans and is found in the directory tut-install/examples/ejb/converter/. This section builds on the example by adding the necessary elements
to secure the application by using the getCallerPrincipal and isCallerInRole methods, which are discussed in more detail in Accessing an Enterprise Bean Caller’s Security Context.

In general, the following steps are necessary when using the getCallerPrincipal and isCallerInRole methods with an
enterprise bean. In the example application included with this tutorial, many
of these steps have been completed for you and are listed here simply to show
what needs to be done should you wish to create a similar application.

Modifying ConverterBean

The source code for the original ConverterBean class
was modified to add the if..else clause that tests whether
the caller is in the role of TutorialUser. . If the user
is in the correct role, the currency conversion is computed and displayed.
If the user is not in the correct role, the computation is not performed,
and the application displays the result as 0. The code
example can be found in the following file:

To Run the Secure Converter Example

Open a web browser to the following URL:

http://localhost:8080/converter

An Authentication Required dialog box appears.

Type a user name and password combination that corresponds to
a user who has already been created in the file realm of
the GlassFish Server and has been assigned to the group of TutorialUser;
then click OK.

Securing Application Clients

The Java EE authentication requirements for application clients are
the same as for other Java EE components, and the same authentication techniques
can be used as for other Java EE application components. No authentication
is necessary when accessing unprotected web resources.

Authentication is required when accessing protected enterprise beans.
The authentication mechanisms for enterprise beans are discussed in Securing Enterprise Beans.

An application client makes use of an authentication service provided
by the application client container for authenticating its users. The container’s
service can be integrated with the native platform’s authentication
system, so that a single sign-on capability is used. The container can authenticate
the user either when the application is started or when a protected resource
is accessed.

An application client can provide
a class, called a login module, to gather authentication data. If so, the javax.security.auth.callback.CallbackHandler interface must
be implemented, and the class name must be specified in its deployment descriptor.
The application’s callback handler must fully support Callback objects
specified in the javax.security.auth.callback package.

Using Login Modules

An application client can use the Java Authentication and Authorization
Service (JAAS) to create login modules for authentication.
A JAAS-based application implements the javax.security.auth.callback.CallbackHandler interface so that it can interact with users to enter specific
authentication data, such as user names or passwords, or to display error
and warning messages.

Applications implement the CallbackHandler interface
and pass it to the login context, which forwards it directly to the underlying
login modules. A login module uses the callback handler both to gather input,
such as a password or smart card PIN, from users and to supply information,
such as status information, to users. Because the application specifies the
callback handler, an underlying login module can remain independent of the
various ways that applications interact with users.

For example, the implementation of a callback handler for a GUI application
might display a window to solicit user input. Or the implementation of a callback
handler for a command-line tool might simply prompt the user for input directly
from the command line.

The login module passes an array of appropriate callbacks to the callback
handler’s handle method, such as a NameCallback for the user name and a PasswordCallback for
the password; the callback handler performs the requested user interaction
and sets appropriate values in the callbacks. For example, to process a NameCallback, the CallbackHandler might
prompt for a name, retrieve the value from the user, and call the setName method of the NameCallback to store the name.

Using Programmatic Login

Programmatic login enables the client code to supply user credentials.
If you are using an EJB client, you can use the com.sun.appserv.security.ProgrammaticLogin class with its convenient login and logout methods. Programmatic login is specific to a server.

Securing Enterprise Information Systems Applications

In EIS applications, components request a connection to an EIS resource.
As part of this connection, the EIS can require a sign-on for the requester
to access the resource. The application component provider has two choices
for the design of the EIS sign-on:

Container-managed sign-on:
The application component lets the container take the responsibility of configuring
and managing the EIS sign-on. The container determines the user name and password
for establishing a connection to an EIS instance. For more information, see Container-Managed Sign-On.

Component-managed sign-on:
The application component code manages EIS sign-on by including code that
performs the sign-on process to an EIS. For more information, see Component-Managed Sign-On.

Container-Managed Sign-On

In container-managed sign-on, an application component does not have
to pass any sign-on security information to the getConnection() method.
The security information is supplied by the container, as shown in the following
example:

Component-Managed Sign-On

In component-managed sign-on, an application component is responsible
for passing the needed sign-on security information to the resource to the getConnection method. For example, security information might be
a user name and password, as shown here:

Configuring Resource Adapter Security

A resource adapter is a system-level software component that typically
implements network connectivity to an external resource manager. A resource
adapter can extend the functionality of the Java EE platform either by implementing
one of the Java EE standard service APIs, such as a JDBC driver, or by defining
and implementing a resource adapter for a connector to an external application
system. Resource adapters can also provide services that are entirely local,
perhaps interacting with native resources. Resource adapters interface with
the Java EE platform through the Java EE service provider interfaces (Java
EE SPI). A resource adapter that uses the Java EE SPIs to attach to the Java
EE platform will be able to work with all Java EE products.

To configure the security settings for a resource adapter, you need
to edit the resource adapter descriptor file, ra.xml.
Here is an example of the part of an ra.xml file that
configures the following security properties for a resource adapter:

You can find out more about the options for configuring resource adapter
security by reviewing as-install/lib/dtds/connector_1_0.dtd.
You can configure the following elements in the resource adapter deployment
descriptor file:

Authentication mechanisms:
Use the authentication-mechanism element to specify an
authentication mechanism supported by the resource adapter. This support is
for the resource adapter, not for the underlying EIS instance.

Security permissions: Use
the security-permission element to specify a security permission
that is required by the resource adapter code. Support for security permissions
is optional and is not supported in the current release of the GlassFish Server.
You can, however, manually update the server.policy file
to add the relevant permissions for the resource adapter.

The
security permissions listed in the deployment descriptor are different from
those required by the default permission set as specified in the connector
specification.

In addition to specifying resource adapter security in the ra.xml file, you can create a security map for a connector connection
pool to map an application principal or a user group to a back-end EIS principal.
The security map is usually used if one or more EIS back-end principals are
used to execute operations (on the EIS) initiated by various principals or
user groups in the application.

To Map an Application Principal to EIS Principals

When using the GlassFish Server, you can use security maps to map the caller
identity of the application (principal or user group) to a suitable EIS principal
in container-managed transaction-based scenarios. When an application principal
initiates a request to an EIS, the GlassFish Server first checks for an exact
principal by using the security map defined for the connector connection pool
to determine the mapped back-end EIS principal. If there is no exact match,
the GlassFish Server uses the wildcard character specification, if any, to determine
the mapped back-end EIS principal. Security maps are used when an application
user needs to execute EIS operations that require to be executed as a specific
identity in the EIS.

To work with security maps, use the Administration Console. From the Administration Console,
follow these steps to get to the security maps page.

In the navigation tree, expand the Resources node.

Expand the Connectors node.

Select the Connector Connection Pools node.

On the Connector Connection Pools page, click the name of the
connection pool for which you want to create a security map.

Click the Security Maps tab.

Click New to create a new security map for the connection pool.

Type a name by which you will refer to the security map, as well
as the other required information.