The Java EE 5 Tutorial

Chapter 28 Introduction to Security in the Java EE Platform

This and subsequent chapters discuss how to address security requirements in Java EE, web, and web services applications. Every enterprise that has 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 implementation mechanisms. More information on these concepts and mechanisms can be found in the Security chapter of the Java EE 5 specification. This document is available for download online at http://www.jcp.org/en/jsr/detail?id=244.

Other chapters in this tutorial that address security requirements include the following:

Some of the material in this chapter assumes that you understand basic security concepts. To learn more about these concepts, you should explore the Java SE security web site before you begin this chapter. The URL for this site is http://java.sun.com/javase/6/docs/technotes/guides/security/.

This tutorial assumes deployment onto the Application Server and provides some information regarding configuration of the Application Server. The best source for information regarding configuration of the Application Server, however, is the Sun Java System Application Server 9.1 Administration Guide. The best source for development tips specific to the Application Server is the Sun Java System Application Server 9.1 Developer’s Guide. The best source for tips on deploying applications to the Application Server is the Sun Java System Application Server 9.1 Application Deployment Guide.

Overview of Java EE Security

Java EE, web, and web services applications are made up of components that can be deployed into different containers. These components are used to build a multitier enterprise application. Security for components is provided by their containers. A container provides two kinds of security: declarative and 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 JSP user interface, and enterprise bean business logic.

In the following example, which is taken from JSR-244, the Java EE 5 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 28–1.

Figure 28–1 Initial Request

Diagram of initial request from web client to web server
for access to a protected resource

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 web server) detects this and invokes the appropriate authentication mechanism for this resource. For more information on these mechanisms, read Security Implementation Mechanisms.

Step 2: Initial Authentication

The web server returns a form that the web client uses to collect authentication data (for example, 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 28–2.

Figure 28–2 Initial Authentication

Diagram of initial authentication: server sends form
to client, which sends authentication data to server for validation

The validation mechanism may be local to a server, or it may leverage the underlying security services. On the basis of the validation, the web server sets a credential for the user.

Step 3: URL Authorization

The credential is used for future determinations of whether the user is authorized to access restricted resources it may request. The web server consults the security policy (derived from the deployment descriptor) associated with the web resource to determine the security roles that are permitted access to the resource. The web container then tests the user’s credential against each role to determine if it can map the user to the role. Figure 28–3 shows this process.

Figure 28–3 URL Authorization

Diagram of 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 28–4.

Figure 28–4 Fulfilling the Original Request

Diagram of request fulfillment, showing server returning
result to client

In our example, the response URL of a JSP page is returned, enabling the user to post form data that needs to be handled by the business logic component of the application. Read Chapter 30, Securing Web Applications for more information on protecting web applications.

Step 5: Invoking Enterprise Bean Business Methods

The JSP page performs the remote method call to the enterprise bean, using the user’s credential to establish a secure association between the JSP page and the enterprise bean (as shown in Figure 28–5). The association is implemented as two related security contexts, one in the web server and one in the EJB container.

Figure 28–5 Invoking an Enterprise Bean Business Method

Diagram of authorization process between JSP/servlet
object and enterprise bean

The EJB container is responsible for enforcing access control on the enterprise bean method. It consults the security policy (derived from the deployment descriptor) associated with the enterprise bean to determine the security roles that are permitted access to the method. For each role, the EJB container uses the security context associated with the call to determine if it can map the caller to the role.

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 JSP 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 JSP, and ultimately to the user by the web server and the web client.

Read Chapter 29, Securing Java EE Applications for more information on protecting web applications.

Security Functions

A properly implemented security mechanism will provide the following functionality:

Ideally, properly implemented security mechanisms will also provide the following functionality:

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.

These and several other well-defined characteristics of application security that, when properly addressed, help to minimize the security threats faced by an enterprise, include the following:

Security Implementation 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 Implementation Mechanisms

Java SE provides support for a variety of security features and mechanisms, including:

Java SE also provides a set of tools for managing keystores, certificates, and policy files; generating and verifying JAR signatures; and obtaining, listing, and managing Kerberos tickets.

For more information on Java SE security, visit its web page at http://java.sun.com/javase/6/docs/technotes/guides/security/.

Java EE Security Implementation Mechanisms

Java EE security services are provided by the component container and can be implemented using declarative or programmatic techniques (container security is discussed more in 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. Application-layer security provides security services for a specific application type tailored to the needs of the application. At the application layer, application firewalls can be employed 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 only protect data while it is residing in the application environment. In the context of a traditional application, this is not necessarily a problem, but when applied to a web services application, where 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:

The disadvantages of using application-layer security include the following:

For more information on providing security at the application layer, read Securing Containers.

Transport-Layer Security

Transport-layer security is provided by the transport mechanisms used to transmit information over the wire between clients and providers, thus transport-layer security relies on secure HTTP transport (HTTPS) using Secure Sockets Layer (SSL). Transport security is a point-to-point security mechanism that can be used for authentication, message integrity, and confidentiality. When running over an SSL-protected session, the server and client can authenticate one another and negotiate an encryption algorithm and cryptographic keys before the application protocol transmits or receives its first byte of data. Security is “live” from the time it leaves the consumer until it arrives at the provider, or vice versa, even across intermediaries. The problem is that it is not protected once it gets to its destination. One solution is to encrypt the message before sending.

Transport-layer security is performed in a series of phases, which are listed here:

Digital certificates are necessary when running secure HTTP transport (HTTPS) using Secure Sockets Layer (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 Application Server. If you are using a different server, use the procedure outlined in Working with Digital Certificates to set up a digital certificate that can be used by your web or application server to enable SSL.

The advantages of using transport-layer security include the following:

The disadvantages of using transport-layer security include the following:

For more information on transport-layer security, read Establishing a Secure Connection Using SSL.

Message-Layer Security

In message-layer security, security information is contained within the SOAP message and/or SOAP message attachment, which allows security information to travel along with the message or attachment. For example, a portion of the message may be signed by a sender and encrypted for a particular receiver. When the message is sent from the initial sender, it 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 only be decrypted 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:

The disadvantage of using message-layer security is that it is relatively complex and adds some overhead to processing.

The Application Server supports message security. It uses Web Services Security (WSS) to secure messages. Because this message security is specific to the Application Server and not a part of the Java EE platform, this tutorial does not discuss using WSS to secure messages. See the Sun Java System Application Server 9.1 Administration Guide and Sun Java System Application Server 9.1 Developer’s Guide for more information.

Securing Containers

In Java EE, the component containers are responsible for providing application security. A container provides two types of security: declarative and programmatic. The following sections discuss these concepts in more detail.

Using Deployment Descriptors for Declarative Security

Declarative security expresses an application component’s security requirements using deployment descriptors. A deployment descriptor is an XML document with an .xml extension that describes the deployment settings of an application, a module, or a component. 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 application, module, or component accordingly.

This tutorial does not document how to write the deployment descriptors from scratch, only what configurations each example requires its deployment descriptors to define. For help with writing deployment descriptors, you can view the provided deployment descriptors in a text editor. Each example’s deployment descriptors are stored at the top layer of each example’s directory. Another way to learn how to write deployment descriptors is to read the specification in which the deployment descriptor elements are defined.

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.

Different types of components use different formats, or schema, for their deployment descriptors. The security elements of deployment descriptors which are discussed in this tutorial include the following:

Using Annotations

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 using annotations. When the application is deployed, this information is used by the Application Server. Not all security information can be specified using annotations, however. Some information must be specified in the application deployment descriptors.

Annotations let you avoid writing boilerplate code under many circumstances by enabling tools to generate it from annotations in the source code. This leads to a declarative programming style, where the programmer says what should be done and tools emit the code to do it. It also eliminates the need for maintaining side files that must be kept up to date with changes in source files. Instead the information can be maintained in the source file.

In this tutorial, specific annotations that can be used to specify security information within a class file are described in the following sections:

The following are sources for more information on annotations:

Links to this information are provided in Further Information about Security.

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 two methods of the EJBContext interface and two methods of the servlet HttpServletRequest interface. These methods allow components to make business logic decisions based on the security role of the caller or remote user.

Programmatic security is discussed in more detail in the following sections:

Securing the Application Server

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

The following features are specific to the Application Server:

For more information about configuring the Application Server, read the Sun Java System Application Server 9.1 Developer’s Guide and Sun Java System Application Server 9.1 Administration Guide.

Working with Realms, Users, Groups, and Roles

You often 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. These concepts are discussed in more detail in Characteristics of Application Security.

    This section discusses setting up users so that they can be correctly identified and either given access to protected resources, or denied access if the user is not authorized to access the protected resources. To authenticate a user, you need to follow these basic steps:

  1. The Application Developer writes code to prompt the user for their user name and password. The different methods of authentication are discussed in Specifying an Authentication Mechanism.

  2. The Application Developer communicates how to set up security for the deployed application by use of a deployment descriptor. This step is discussed in Setting Up Security Roles.

  3. The Server Administrator sets up authorized users and groups on the Application Server. This is discussed in Managing Users and Groups on the Application Server.

  4. The Application Deployer maps the application’s security roles to users, groups, and principals defined on the Application Server. This topic is discussed in Mapping Roles to Users and Groups.

What Are Realms, Users, Groups, and Roles?

A realm is defined on a web or application server. It contains a collection of users, which may or may not be assigned to a group, that are controlled by the same authentication policy. Managing users on the Application Server is discussed in Managing Users and Groups on the Application Server.

An application will often prompt a user for their user name and password before allowing access to a protected resource. After the user has entered their user name and password, 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 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 group defined on the application server. Figure 28–6 shows this. More information on mapping roles to users and groups can be found in Setting Up Security Roles.

Figure 28–6 Mapping Roles to Users and Groups

Diagram of role mapping, showing creation of users and
groups, definition of roles, and mapping of roles to users and groups

The following sections provide more information on realms, users, groups, and roles.

What Is a Realm?

For a web application, a realm is a complete database of users and groups that identify valid users of a web application (or a set of web applications) and are controlled by the same authentication policy.

The Java EE server authentication service can govern users in multiple realms. In this release of the Application Server, the file, admin-realm, and certificate realms come preconfigured for the Application Server.

In the file realm, the server stores user credentials locally in a file named keyfile. You can use the Admin 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 the HTTPS protocol 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 the HTTPS protocol 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 FileRealm and stores administrator user credentials locally in a file named admin-keyfile. You can use the Admin 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 Application Server.

What Is a User?

A user is an individual (or application program) identity that has been defined in the Application Server. In a web application, a user can have a set of roles associated with that identity, which entitles them 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 on 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 Application Server.

A Java EE user of the file realm can belong to an Application Server group. (A user in the certificate realm cannot.) An Application Server group 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.

An Application Server group has a different scope from a role. An Application Server group is designated for the entire Application Server, whereas a role is associated only with a specific application in the Application 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:

Managing Users and Groups on the Application Server

Managing users on the Application Server is discussed in more detail in the Sun Java System Application Server 9.1 Administration Guide.

This tutorial provides steps for managing users that will need to be completed to work through the tutorial examples.

Adding Users to the Application Server

    To add users to the Application Server, follow these steps:

  1. Start the Application Server if you haven’t already done so. Information on starting the Application Server is available in Starting and Stopping the Application Server.

  2. Start the Admin Console if you haven’t already done so. You can start the Admin Console by starting a web browser and entering the URL http://localhost:4848/asadmin. If you changed the default Admin port during installation, enter the correct port number in place of 4848.

  3. To log in to the Admin Console, enter the user name and password of a user in the admin-realm who belongs to the asadmin group. The name and password entered during installation will work, as will any users added to this realm and group subsequent to installation.

  4. Expand the Configuration node in the Admin Console tree.

  5. Expand the Security node in the Admin Console tree.

  6. Expand the Realms node.

    • Select the file realm to add users you want to enable to access applications running in this realm. (For the example security applications, select the file realm.)

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

    • You cannot enter users into the certificate realm using the Admin Console. You can only add certificates to the certificate realm. For information on adding (importing) certificates to the certificate realm, read Adding Users to the Certificate Realm.

  7. Click the Manage Users button.

  8. Click New to add a new user to the realm.

  9. Enter the correct information into the User ID, Password, and Group(s) fields.

    • If you are adding a user to the file realm, enter the name to identify the user, a password to allow the user access to the realm, and a group to which this user belongs. For more information on these properties, read Working with Realms, Users, Groups, and Roles.

      For the example security applications, enter a user with any name and password you like, but make sure that the user is assigned to the group of user.

    • If you are adding a user to the admin-realm, enter the name to identify the user, a password to allow the user access to the Application Server, and enter asadmin in the Group field.

  10. Click OK to add this user to the list of users in the realm.

  11. Click Logout when you have completed this task.

Adding Users to the Certificate Realm

In the certificate realm, user identity is set up in the Application 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 28–6.

For applications, you define security roles in the Java EE deployment descriptor file application.xml, and the corresponding role mappings in the Application Server deployment descriptor file sun-application.xml. For individually deployed web or EJB modules, you define roles in the Java EE deployment descriptor files web.xml or ejb-jar.xml and the corresponding role mappings in the Application Server deployment descriptor files sun-web.xml or sun-ejb-jar.xml.

The following is an example of a security constraint from a web.xml application deployment descriptor file where the role of DEPT-ADMIN is authorized for methods that review employee data and the role of DIRECTOR is authorized for methods that change employee data.

<security-constraint>
    <web-resource-collection>
        <web-resource-name>view dept data</web-resource-name>
        <url-pattern>/hr/employee/*</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
        <role-name>DEPT_ADMIN</role-name>
    </auth-constraint>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

<security-constraint>
    <web-resource-collection>
        <web-resource-name>change dept data</web-resource-name>
        <url-pattern>/hr/employee/*</url-pattern>
        <http-method>GET</http-method>
        <http-method>PUT</http-method>
    </web-resource-collection>
    <auth-constraint>
        <role-name>DIRECTOR</role-name>
    </auth-constraint>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

The web.xml application deployment descriptor is described in more detail in Declaring Security Requirements in a Deployment Descriptor.

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. This step is discussed in the following section.

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. To map a role name permitted by the application or module to principals (users) and groups defined on the server, use the security-role-mapping element in the runtime deployment descriptor (sun-application.xml, sun-web.xml, or sun-ejb-jar.xml) file. The entry needs to declare a mapping between a security role used in the application and one or more groups or principals defined for the applicable realm of the Application Server. An example for the sun-web.xml file is shown below:

<sun-web-app>
    <security-role-mapping>
        <role-name>DIRECTOR</role-name>
        <principal-name>mcneely</principal-name>
    </security-role-mapping>
    <security-role-mapping>
        <role-name>MANAGER</role-name>
        <group-name>manager</group-name>
    </security-role-mapping>
</sun-web-app>

The role name can be mapped to either a specific principal (user), a group, or both. The principal or group names referenced must be valid principals or groups in the current default realm of the Application Server. The role-name in this example must exactly match the role-name in the security-role element of the corresponding web.xml file or the role name defined in the @DeclareRoles or @RolesAllowed annotations.

Sometimes the role names used in the application are the same as the group names defined on the Application Server. Under these circumstances, you can enable a default principal-to-role mapping on the Application Server using the Admin Console. From the Admin Console, select Configuration, then Security, then check the enable box beside Default Principal to Role Mapping. If you need more information about using the Admin Console, see Adding Users to the Application Server.

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 that is being sent 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.

Installing and Configuring SSL Support

An SSL HTTPS connector is already enabled in the Application Server. For more information on configuring SSL for the Application Server, refer to the Sun Java System Application Server 9.1 Administration Guide.

If you are using a different application server or web server, an SSL HTTPS connector might or might not be enabled. If you are using a server that needs its SSL connector to be configured, consult the documentation for that server.

As a general rule, to enable SSL for a server, you must address the following issues:

You can verify whether or not SSL is enabled by following the steps in Verifying SSL Support.

Specifying a Secure Connection in Your Application Deployment Descriptor

To specify a requirement that protected resources be received over a protected transport layer connection (SSL), specify a user data constraint in the application deployment descriptor. The following is an example of a web.xml application deployment descriptor that specifies that SSL be used:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>view dept data</web-resource-name>
        <url-pattern>/hr/employee/*</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
        <role-name>DEPT_ADMIN</role-name>
    </auth-constraint>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

A user data constraint (<user-data-constraint> in the deployment descriptor) requires that all constrained URL patterns and HTTP methods specified in the security constraint are received over a protected transport layer connection such as HTTPS (HTTP over SSL). A user data constraint specifies a transport guarantee (<transport-guarantee> in the deployment descriptor). The choices for transport guarantee include CONFIDENTIAL, INTEGRAL, or NONE. If you specify CONFIDENTIAL or INTEGRAL as a security constraint, that type of security constraint applies to all requests that match the URL patterns in the web resource collection and not just to the login dialog box.

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

The user data constraint is handy to use 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.

Verifying SSL Support

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

Tips on Running SSL

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 login pages, personal information pages, shopping cart checkouts, or any pages where credit card information could possibly be transmitted. 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, where 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, CA-signed certificates). 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.

Working with Digital Certificates

Digital certificates for the Application Server have already been generated and can be found in the directory 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.

The instructions in this section apply to the developer and cluster profiles of the Application Server. In the enterprise profile, the certutil utility is used to create digital certificates. For more information, see the Sun Java System Application Server 9.1 Administration Guide.

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. It 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 certificate authority (CA) such as VeriSign or Thawte. If your server certificate is self-signed, you must install it in the Application Server keystore file (keystore.jks). If your client certificate is self-signed, you should install it in the Application 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. If data is encrypted with one key, it 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 the value using its private key. The encrypted value is called a digital signature. The client decrypts the encrypted value 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 the HTTPS protocol 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 Java SE SDK. It enables users to administer their own public/private key pairs and associated certificates for use in self-authentication (where the user authenticates himself or herself to other users or services) or data integrity and authentication services, using digital signatures. It 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, read the keytool documentation at http://java.sun.com/javase/6/docs/technotes/tools/solaris/keytool.html.

Creating a Server Certificate

A server certificate has already been created for the Application Server. The certificate 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 or one server’s identity. It 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.

    To create a server certificate, follow these steps:

  1. Create the keystore.

  2. Export the certificate from the keystore.

  3. Sign the certificate.

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

Run keytool to generate the server keystore, keystore.jks. This step 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 using an algorithm of type RSA, with a default password of changeit. For more information on keytool options, see its online help at http://java.sun.com/javase/6/docs/technotes/tools/solaris/keytool.html.


Note –

RSA is public-key encryption technology developed by RSA Data Security, Inc. The acronym stands for Rivest, Shamir, and Adelman, the inventors of the technology.


    From the directory in which you want to create the keystore, run keytool with the following parameters.

  1. Generate the server certificate. (Type the keytool command all on one line.)


    java-home\bin\keytool -genkey -alias server-alias-keyalg RSA -keypass changeit 
    -storepass changeit -keystore keystore.jks
    

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

    You must enter 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 specified in the keystore must match the host identified in the javaee.server.name property specified in the file tut-install/javaeetutorial5/examples/bp-project/build.properties.

  2. Export the generated server certificate in keystore.jks into the file server.cer. (Type the keytool all on one line.)


    java-home\bin\keytool -export -alias server-alias -storepass changeit 
    -file server.cer -keystore keystore.jks
    
  3. If you want to have the certificate signed by a CA, read Signing Digital Certificates for more information.

  4. To create the truststore file cacerts.jks and add the server certificate to the truststore, run keytool from the directory where you created the keystore and server certificate. Use the following parameters:


    java-home\bin\keytool -import -v -trustcacerts -alias server-alias -file server.cer 
    -keystore cacerts.jks -keypass changeit -storepass changeit
    

    Information on the certificate, such as that shown next, will display.


    % keytool -import -v -trustcacerts -alias server-alias -file server.cer 
    -keystore cacerts.jks -keypass changeit -storepass changeit
    Owner: CN=localhost, OU=Sun Micro, O=Docs, L=Santa Clara, ST=CA, 
    C=USIssuer: CN=localhost, OU=Sun Micro, O=Docs, L=Santa Clara, ST=CA, 
    C=USSerial number: 3e932169Valid from: Tue Apr 08Certificate 
    fingerprints:MD5: 52:9F:49:68:ED:78:6F:39:87:F3:98:B3:6A:6B:0F:90 SHA1: 
    EE:2E:2A:A6:9E:03:9A:3A:1C:17:4A:28:5E:97:20:78:3F:
    Trust this certificate? [no]:
  5. Enter yes, and then press the Enter or Return key. The following information displays:


    Certificate was added to keystore[Saving cacerts.jks]

Signing Digital Certificates

After you’ve created a digital certificate, you will want to have it signed by its owner. After the digital certificate has been cryptographically signed by its owner, it is difficult for anyone else to forge. For sites involved in e-commerce or any other business transaction in which authentication of identity is important, a certificate can be purchased from a well-known certificate authority such as VeriSign or Thawte.

As mentioned earlier, if authentication is not really a concern, you can save the time and expense involved in obtaining a CA certificate and simply use the self-signed certificate.

Obtaining a Digitally Signed Certificate

    This example assumes that the keystore is named keystore.jks, the certificate file is server.cer, and the CA file is cacerts.jks. To get your certificate digitally signed by a CA:

  1. Generate a Certificate Signing Request (CSR).


    keytool -certreq -alias server-alias -keyalg RSA -file csr-filename 
    -keystore cacerts.jks
    
  2. Send the contents of the csr-filename for signing.

  3. If you are using Verisign CA, go to http://digitalid.verisign.com/. Verisign will send the signed certificate in email. Store this certificate in a file.

Using a Different Server Certificate with the Application Server

Follow the steps in Creating a Server Certificate, to create your own server certificate, have it signed by a CA, and import the certificate into keystore.jks.

Make sure that when you create the certificate, you follow these rules:

    To specify that the Application Server should use the new keystore for authentication and authorization decisions, you must set the JVM options for the Application Server so that they recognize the new keystore. To use a different keystore than the one provided for development purposes, follow these steps.

  1. Start the Application Server if you haven’t already done so. Information on starting the Application Server can be found in Starting and Stopping the Application Server.

  2. Start the Admin Console. Information on starting the Admin Console can be found in Starting the Admin Console.

  3. Select Application Server in the Admin Console tree.

  4. Select the JVM Settings tab.

  5. Select the JVM Options tab.

  6. Change the following JVM options so that they point to the location and name of the new keystore. There current settings are shown below:


    -Djavax.net.ssl.keyStore=${com.sun.aas.instanceRoot}/config/keystore.jks
    -Djavax.net.ssl.trustStore=${com.sun.aas.instanceRoot}/config/cacerts.jks
    
  7. If you’ve changed the keystore password from its default value, you need to add the password option as well:


    -Djavax.net.ssl.keyStorePassword=your-new-password
    
  8. Log out of the Admin Console and restart the Application Server.

Miscellaneous Commands for Certificates

To check the contents of a keystore that contains a certificate with an alias server-alias, use this command:


keytool -list -keystore keystore.jks -alias server-alias -v

To check the contents of the cacerts file, use this command:


keytool -list -keystore cacerts.jks

Enabling Mutual Authentication over SSL

This section discusses setting up client-side authentication. When both server-side and client-side authentication are enabled, it is called mutual, or two-way, authentication. In client authentication, clients are required to submit certificates that are issued by a certificate authority that you choose to accept.

There are at least two ways to enable mutual authentication over SSL:

When client authentication is enabled in both of these ways, client authentication will be performed twice.

Creating a Client Certificate for Mutual Authentication

If you have a certificate signed by a trusted Certificate Authority (CA) such as Verisign, and the Application Server cacerts.jks file already contains a certificate verified by that CA, you do not need to complete this step. You only need to install your certificate in the Application Server certificate file when your certificate is self-signed.

From the directory where you want to create the client certificate, run keytool as outlined here. When you press Enter, keytool prompts you to enter the server name, organizational unit, organization, locality, state, and country code.

You must enter 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. The host specified in the keystore must match the host identified in the javee.server.host variable specified in your tut-install/javaeetutorial5/examples/bp-project/build.properties file. If this example is to verify mutual authentication and you receive a runtime error stating that the HTTPS host name is wrong, re-create the client certificate, being sure to use the same host name that you will use when running the example. For example, if your machine name is duke, then enter duke as the certificate CN or when prompted for first and last names. When accessing the application, enter a URL that points to the same location (for example, https://duke:8181/mutualauth/hello). This is necessary because during SSL handshake, the server verifies the client certificate by comparing the certificate name and the host name from which it originates.

    To create a keystore named client_keystore.jks that contains a client certificate named client.cer, follow these steps:

  1. Create a backup copy of the server truststore file. To do this,

    1. Change to the directory containing the server’s keystore and truststore files, as-install\domains\domain1\config.

    2. Copy cacerts.jks to cacerts.backup.jks.

    3. Copy keystore.jks to keystore.backup.jks.

      Do not put client certificates in the cacerts.jks file. Any certificate you add to the cacerts file effectively means it can be a trusted root for any and all certificate chains. After you have completed development, delete the development version of the cacerts file and replace it with the original copy.

  2. Generate the client certificate. Enter the following command from the directory where you want to generate the client certificate:


    java-home\bin\keytool -genkey -alias client-alias -keyalg RSA -keypass changeit 
    -storepass changeit -keystore client_keystore.jks
    
  3. Export the generated client certificate into the file client.cer.


    java-home\bin\keytool -export -alias client-alias -storepass changeit 
    -file client.cer -keystore client_keystore.jks
    
  4. Add the certificate to the truststore file domain-dir/config/cacerts.jks. Run keytool from the directory where you created the keystore and client certificate. Use the following parameters:


    java-home\bin\keytool -import -v -trustcacerts -alias client-alias 
    -file client.cer -keystore domain-dir/config/cacerts.jks -keypass changeit 
    -storepass changeit
    

    The keytool utility returns a message like this one:


    Owner: CN=localhost, OU=Java EE, O=Sun, L=Santa Clara, ST=CA, C=US
    Issuer: CN=localhost, OU=Java EE, O=Sun, L=Santa Clara, ST=CA, C=US
    Serial number: 3e39e66a
    Valid from: Thu Jan 30 18:58:50 PST 2005 until: Wed Apr 3019:58:50 PDT 2005
    Certificate fingerprints:
        MD5: 5A:B0:4C:88:4E:F8:EF:E9:E5:8B:53:BD:D0:AA:8E:5A
        SHA1:90:00:36:5B:E0:A7:A2:BD:67:DB:EA:37:B9:61:3E:26:B3:89:46:32
    Trust this certificate? [no]: yes
    Certificate was added to keystore
  5. Restart the Application Server.

Further Information about Security

For more information about security in Java EE applications, see: