Skip Headers

Oracle® Application Server Containers for J2EE Standalone User's Guide 10g Release 2 (10.1.2) Part No. B14361-02 |
| Library | Product | Contents | Index

Previous | Next |

# 3 Configuring Security

OC4J security employs a user manager to authenticate and authorize users and groups that attempt to access a J2EE application. User managers differ in performance and are employed based on the security you require. Confidentiality through encryption is supplied with SSL.

This chapter describes the following topics:

- Overview of Security Functions

- Authentication

- Authorization

- Plugging In a User Manager

- Confidentiality Through SSL

For a broader description of Oracle Application Server security, see the Oracle Application Server Security Guide and the Oracle Application Server Containers for J2EE Security Guide.

## 3.1 Overview of Security Functions

OC4J security is based on a two-step process. First, a user or group attempting to access a J2EE application is authenticated, and then it is authorized. Authentication and authorization are provided under various user managers, such as the `JAZNUserManager` and `XMLUserManager` classes. The `JAZNUserManager` class is the default and offers the best security. The `XMLUserManager` is the simplest method for security. The `JAZNUserManager` leverages the OracleAS JAAS Provider as the security infrastructure for OC4J by using either the Lightweight Directory Access Protocol (LDAP)-based or the XML-based provider type. The `XMLUserManager` is configured using a file, so the passwords are visible.

See "Plugging In a User Manager" for details on the OracleAS JAAS Provider, provider types, and user managers. Also, see the Oracle Application Server Containers for J2EE Security Guide for details on the OracleAS JAAS Provider and provider types.

Note: The default user manager was changed from the `XMLUserManager` to the `JAZNUserManager`.

Authentication and authorization, along with OC4J confidentiality, are introduced below:

- Authentication: Verifies the identity and credentials of a user.

  Defines users and groups in a user repository. A user repository is employed by a user manager to verify the identity of a user or group attempting to access a J2EE application. A user repository can be a file or a directory server, depending on your environment. The Oracle Application Server Java Authentication and Authorization Service (JAAS) Provider LDAP user manager and the `XMLUserManager` are two examples of user repositories.

  Although the J2EE application determines which client can access the application, it is the user manager, employing the user name and password, that verifies the client's identity, based on information in the user repository.

- Authorization: Permits or denies users and groups access to an application.

  Specifies authorization for users and groups (identities) in the J2EE and OC4J-specific deployment descriptors. J2EE and OC4J-specific deployment descriptors indicate what roles are needed to access the different parts of the application. Roles are the logical identities that each application uses to indicate access rights to its different objects. The OC4J-specific deployment descriptors provide a mapping between the logical roles and the users and groups known by OC4J.

- Confidentiality Through SSL: Ensures encrypted communications.

  Use Secure Sockets Layer (SSL) over HTTP for encrypted communication.

## 3.2 Authentication

Authentication verifies that the identity and credentials of a user are valid. The J2EE application determines which user can use the application. However, it is the user manager, employing the user name and password, that verifies the user's identity based on information in the user repository. Authentication is distinct from authorization, which is the process of giving a user access to a J2EE application, based on his identity.

OC4J security authenticates two types of clients: HTTP and Enterprise JavaBeans (EJBs). This section describes each of these along with setting up users and groups.

### 3.2.1 Specifying Users and Groups

OC4J supports the definition of users and groups—either shared by all deployed applications or specific to a given application.

- Shared users and groups are listed in the user repository, whose location is specified in the global `config/application.xml` file.

- Application-specific users and groups are listed in the application-specific user repository, whose location is specified in the `orion-application.xml` file of that application.

The way you define users and groups depends on what user manager you employ. For example, because the Oracle Application Server Java Authentication and Authorization Service (JAAS) Provider(OracleAS JAAS Provider) uses roles instead of groups, the `JAZNUserManager` XML-based user repository, `jazn-data.xml`, has a different structure from the `XMLUserManager` user repository, `principals.xml`. In addition, in a `JAZNUserManager` user repository, passwords are encrypted, unlike in `principals.xml`.

The following sections offer examples of how to specify users and groups under the `JAZNUserManager` and `XMLUserManager` classes. See "Plugging In a User Manager" for additional details on these classes.

#### 3.2.1.1 Example: Specifying Users and Groups in jazn-data.xml

The following XML from the `JAZNUserManager` user repository configuration file, `jazn-data.xml`, shows how to define OracleAS JAAS Provider roles (groups) and users. It defines a group named `allusers` and a user named `guest`.

    <role>
      <name>allusers</name>
      <members>
       <member>
        <type>user</type>
        <name>guest</name>
       </member>
      </members>
    </role>

Unlike the XML from the `XMLUserManager` user repository configuration file, `principals.xml`, you can encrypt the password under the `JAZNUserManager`.

    <user>
      <name>guest</name>
      <description>The default user</description>
      <credentials>wEE6aA==</credentials>
    </user>

Note: See the Oracle Application Server Containers for J2EE Security Guide for more information on setting up the `jazn-data.xml` file.

#### 3.2.1.2 Example: Specifying Users and Groups in principals.xml

The following XML from the `principals.xml` file (the user repository configuration file for the `XMLUserManager` class) shows how to define a group named `allusers` and a user named `guest` with password `welcome`. The `guest` user is made a member of the `allusers` group.

If you want to use the `XMLUserManager` class instead of the `JAZNUserManager` class, you must modify the global `application.xml` file, if modifying for all applications, or the `orion-application.xml` file, if using the `XMLUserManager` class only for a specific application. Add the following line:

    <principals path="./principals.xml" />

where the path points to the location of the `principals.xml` file. Also, you must remove or comment out the `<jazn provider>` element in this file.

Note: You can hide the password through password indirection. See the Oracle Application Server Containers for J2EE Security Guide for a description of password indirection.

    <principals>
     <groups>
      <group name="allusers">
       <description>Group for all normal users</description>
       <permission name="rmi:login" />
       <permission name="com.evermind.server.rmi.RMIPermission" />
      </group>
    ....other groups...
     </groups>
     <users>
      <user username="guest" password="welcome">
       <description>Guest user</description>
       <group-membership group="allusers" />
      </user>
     </users>
    </principals>

### 3.2.2 Authenticating HTTP Clients

OC4J requests the client to authenticate itself when accessing protected URLs. You can achieve authentication through a user name and password, or in the case of SSL, through an SSL certificate. Although in most cases where authentication is required, the user is prompted to enter a user name and password. If you decide to use an SSL certificate to authenticate the client, see "Confidentiality Through SSL" for directions on how to set up your client certificate and server keystore.

### 3.2.3 Authenticating EJB Clients

When you access EJBs in OC4J, you must pass valid credentials to this server.

- Standalone clients define their credentials in the `jndi.properties` file, either deployed with the EAR file or in the `InitialContext` object.

- Servlets or JavaBeans running within OC4J pass their credentials within the `InitialContext` object, which is created to look up the remote EJBs.

#### 3.2.3.1 Setting JNDI Properties

If the client exists within the same application as the target, or the target exists within its parent, you do not need a JNDI properties file. If not, you must initialize your JNDI properties either within a `jndi.properties` file, in the system properties, or within your implementation, before the JNDI call. The following sections discuss these three options:

- No JNDI Properties

- JNDI Properties File

- JNDI Properties Within Implementation

##### 3.2.3.1.1 No JNDI Properties

A servlet that exists in the same application with the target bean automatically accesses the JNDI properties for the node. Therefore, accessing the EJB is simple, because no JNDI properties are required.

    //Get the Initial Context for the JNDI lookup for a local EJB
    InitialContext ic = new InitialContext();
    //Retrieve the Home interface using JNDI lookup
    Object empObject = ic.lookup("java:comp/env/employeeBean");

This is also true if the target bean is in an application that has been deployed as this application's parent. To specify parents, use the `-parent` option of the `admin.jar` command when deploying the originating application.

##### 3.2.3.1.2 JNDI Properties File

If you are setting the JNDI properties within the `jndi.properties` file, set the properties as follows. Ensure that this file is accessible from the `CLASSPATH`.

Factory

    java.naming.factory.initial=
    com.evermind.server.ApplicationClientInitialContextFactory

Location

The ORMI default port number is 23791, which you can modify in `j2ee/home/config/rmi.xml`. Therefore, set the URL in the `jndi.properties`, in one of two ways:

    java.naming.provider.url=ormi://hostname/application-name

- or -

    java.naming.provider.url=ormi://hostname:23791/application-name

Security

When you access EJBs in OC4J, you must pass valid credentials to this server. Standalone clients define their credentials in the `jndi.properties` file deployed with the code of the client.

    java.naming.security.principal=username
    java.naming.security.credentials=password

##### 3.2.3.1.3 JNDI Properties Within Implementation

Set the properties with the same values, but with different syntax. For example, JavaBeans running within the container pass their credentials within the `InitialContext`, which is created to look up the remote EJBs.

To pass JNDI properties within the `Hashtable` environment, set these as shown below:

    Hashtable env = new Hashtable();
    env.put("java.naming.provider.url", "ormi://myhost/ejbsamples");
    env.put("java.naming.factory.initial",
          "com.evermind.server.ApplicationClientInitialContextFactory");
    env.put(Context.SECURITY_PRINCIPAL, "guest");
    env.put(Context.SECURITY_CREDENTIALS, "welcome");
    Context ic = new InitialContext (env);
    Object homeObject = ic.lookup("java:comp/env/employeeBean");

    // Narrow the reference to a TemplateHome.
    EmployeeHome empHome =
    	 (EmployeeHome) PortableRemoteObject.narrow(homeObject,
                                                       EmployeeHome.class);

#### 3.2.3.2 Using the Initial Context Factory Classes

For most clients, set the initial context factory class to `ApplicationClientInitialContextFactory`. If you are not using a logical name defined in the `<ejb-ref>` in your XML configuration file, then you must provide the actual JNDI name of the target bean. In this case, you can use a different initial context factory class, the `com.evermind.server.RMIInitialContextFactory` class.

Example 3-1 Servlet Accessing EJB in Remote OC4J Instance

The following servlet uses the JNDI name for the target bean: `/cmpapp/employeeBean`. Thus, this servlet must provide the JNDI properties in an `RMIInitialContext` object, instead of the `ApplicationClientInitialContext` object. The environment is initialized as follows:

- The `INITIAL_CONTEXT_FACTORY` is initialized to a `RMIInitialContextFactory`.

- Instead of creating a new `InitialContext`, it is retrieved.

- The actual JNDI name is used in the lookup.

    Hashtable env = new Hashtable();
    env.put(Context.PROVIDER_URL, "ormi://myhost/cmpapp");
    env.put(Context.SECURITY_PRINCIPAL, "admin");
    env.put(Context.SECURITY_CREDENTIALS, "welcome");
    env.put(Context.INITIAL_CONTEXT_FACTORY,
    "com.evermind.server.rmi.RMIInitialContextFactory");

    Context ic =
    new com.evermind.server.rmi.RMIInitialContextFactory().
    getInitialContext(env);

    Object homeObject = ic.lookup("/cmpapp/employeeBean");

    // Narrow the reference to a TemplateHome.
    EmployeeHome empHome =
    (EmployeeHome) PortableRemoteObject.narrow(homeObject,
    EmployeeHome.class);

## 3.3 Authorization

Authorization is the process of granting or denying a user access to a J2EE application based on its identity. Authorization is distinct from authentication, which is the process of verifying that a user is valid.

Specify authorization for users and groups in the J2EE and OC4J-specific deployment descriptors. The J2EE deployment descriptor is where you specify the access rules for using logical roles. The OC4J-specific deployment descriptor is where you map logical roles to actual users and groups, which are defined in a user repository.

The following sections describe how to define users, groups, and roles:

- Specifying Logical Roles in a J2EE Application

- Mapping Logical Roles to Users and Groups

### 3.3.1 Specifying Logical Roles in a J2EE Application

Specify the logical roles that your application uses in the XML deployment descriptors. Depending on the application component type, update one of the following with the logical roles:

- `web.xml` for the Web component

- `ejb-jar.xml` for the EJB component

- `application.xml` for the application

In each of these deployment descriptors, the roles are defined by an XML element named `<security-role>`.

Example 3-2 EJB JAR Security Role Definition

The following steps describe the XML necessary to create a logical role named `VISITOR` in the `ejb-jar.xml` deployment descriptor.

1. Define the logical security role, `VISITOR`, in the `<security-role>` element.

       <security-role>
        <description>A role for every user</description>
        <role-name>VISITOR</role-name>
       </security-role>

2. Define the bean and methods that this role can access in the `<method-permission>` element.

       <method-permission>
        <description>VISITOR role needed for CustomerBean methods</description>
        <role-name>VISITOR</role-name>
        <method>
         <ejb-name>customerbean</ejb-name>
         <method-name>*</method-name>
        </method>
       </method-permission>

### 3.3.2 Mapping Logical Roles to Users and Groups

Map logical roles defined in the application deployment descriptors to actual users and groups defined in a user repository. The mapping is specified in the OC4J-specific deployment descriptor with a `<security-role-mapping>` element. Figure 3-1 illustrates this mapping.

Figure 3-1 Mapping Logical Roles to Users and Groups Defined in jazn-data.xml

Description of "Figure 3-1 Mapping Logical Roles to Users and Groups Defined in jazn-data.xml"

Note: The security role mapping layer, either defined in the `principals.xml` or `jazn-data.xml` file, is bypassed if the following conditions are true: The name of the security role and group (or roles, as in the case of `jazn-data.xml`) are the same. No security role mapping is specified.

Example 3-3 Mapping Logical Role to Actual Role

This example maps the logical role `VISITOR` to the `allusers` group in the `orion-ejb-jar.xml` file. Any user that can log in as part of this group is considered to have the `VISITOR` role and can therefore execute the methods of `customerbean`. This role is mapped to the `allusers` group, which is defined in the User Manager configuration file—the `jazn-data.xml` file.

    <security-role-mapping name="VISITOR">
     <group name="allusers" />
    </security-role-mapping>

Note: You can map a logical role to a single group or to several groups.

## 3.4 Plugging In a User Manager

Any user manager class providing OC4J security is an implementation of the `com.evermind.security.UserManager` interface. This includes any custom user managers you create. User manager classes manage users, groups, and passwords with such methods as `createUser()`, `getUser()`, and `getGroup()`. Table 3-1 lists the user managers that you can employ in OC4J security.

Table 3-1 User Managers and Their User Repositories Available to OC4J

User Manager | User Repository
--- | ---
oracle.security.jazn.oc4j.`JAZNUserManager` | using the XML-based provider type—`jazn-data.xml` using the LDAP-based provider type—OID
com.evermind.server.`XMLUserManager` | `principals.xml`
Custom user manager | user-provided user repository

By default, OC4J reads the user names, groups, and passwords from the `JAZNUserManager` user repository, `jazn-data.xml`. In order for OC4J to employ any user manager, you must specify the name of the user manager class in one of the following XML files:

- `orion-application.xml`—file for a single application

- `config/application.xml`—global configuration file for all applications in the server

The following sections describe how to configure each User Manager type:

- Using the JAZNUserManager Class

- Using the XMLUserManager Class

- Creating Your Own User Manager

### 3.4.1 Using the JAZNUserManager Class

The primary purpose of the `JAZNUserManager` class is to leverage the OracleAS JAAS Provider as the security infrastructure for OC4J. For a complete description of the OracleAS JAAS Provider, see the Oracle Application Server Containers for J2EE Security Guide.

By integrating the OracleAS JAAS Provider with OC4J, the following benefits can be achieved:

- Single Sign-on (SSO)/`mod_osso` integration

- SSL/`mod_ossl` integration

- OID integration (using the LDAP-based provider type)

- Fine-grained access control using Java2 permissions

- `run-as` identity support, delegation support (from servlet to EJB)

- Secure file-based storage of passwords (using the XML-based provider type)

Use the `JAZNUserManager` class if you want OC4J security that has secure, centralized storage, retrieval, and administration of OracleAS JAAS Provider data. This data consists of realm (user and roles) and OracleAS JAAS Provider policy (permissions) information. Figure 3-2 illustrates the architecture of OC4J security under the `JAZNUserManager` class.

The `JAZNUserManager` class can use two types of OracleAS JAAS Providers for OC4J security. Use the provider type that is appropriate for your environment:

- LDAP-based

  For centralized storage of information in a directory. The user repository is OID.

- XML-based

  For lightweight storage of information in an XML file. The user repository is the `jazn-data.xml` file.

Figure 3-2 OC4J Security Architecture Under the JAZNUserManager Class

Description of "Figure 3-2 OC4J Security Architecture Under the JAZNUserManager Class"

In OC4J, you can configure your application(s) to use the `JAZNUserManager` class by adding the `<jazn>` or `<user-manager>` element in your OC4J-specific configuration file (`config/application.xml` or `orion-application.xml`).

#### 3.4.1.1 Using the JAZNUserManager Class with the LDAP-Based Provider Type

The LDAP-based provider type delegates user and group management functionality to the Delegated Administrative Service (DAS) from OID.

The following examples from an OC4J-specific configuration file have OC4J employ the `JAZNUserManager` class as the user manager with the LDAP-based provider type.

    <jazn provider="LDAP" default-realm="sample_subrealm"

    location="ldap://myoid:389" />

- or -

    <user-manager class="oracle.security.jazn.oc4j.JAZNUserManager">

    <property name="provider.type" value="LDAP" />
    <property name="realm.default" value="sample_subrealm" />
    <property name="ldap.service"  value="ldap://myoid:389" />

    </user-manager>

Notes: If you specify both the `<user-manager>` element and the `<jazn>` element, then the `<jazn>` element is ignored.

#### 3.4.1.2 Using the JAZNUserManager Class with the XML-Based Provider Type

The XML-based provider type is a fast, lightweight implementation of the OracleAS JAAS Provider API. This provider type uses XML to store user names and encrypted passwords.

The following examples from an OC4J-specific configuration file have OC4J employ the `JAZNUserManager` class as the user manager with the XML-based provider type. The user repository is located at `.../j2ee/home/jazn/config/``jazn-data.xml`. Because there is only one realm in the data file, the specification of `realm.default` is not needed.

    <jazn provider="XML"

    location=".../j2ee/home/config/jazn-data.xml" />

- or -

    <user-manager class="oracle.security.jazn.oc4j.JAZNUserManager">

    <property name="provider.type" value="XML" />
    <property name="xml.store.fs.jazn"

    value=".../j2ee/home/config/jazn-data.xml" />

    </user-manager>

Notes: If you specify both the `<user-manager>` element and the `<jazn>` element, then the `<jazn>` element is ignored.

### 3.4.2 Using the XMLUserManager Class

The `XMLUserManager` is a file-based security model, where all of your users, roles, groups, and passwords are stored in `principals.xml`. This is not secure as your passwords could be in the clear.

However, if you want to use the `XMLUserManager` class instead of the `JAZNUserManager` class, you must modify the global `application.xml` file, if modifying for all applications, or the `orion-application.xml` file, if using the `XMLUserManager` class only for a specific application. Add the following line:

    <principals path="./principals.xml" />

where the path points to the location of the `principals.xml` file. Also, you must remove or comment out the `<jazn>` element in this file. If you do not remove or comment out the `<jazn>` element, then whichever element is specified first is the User Manager for the applications. For example, if you have the following:

    <principals path="./principals.xml" />
    <jazn provider="XML"

    location=".../j2ee/home/config/jazn-data.xml" />

In this case, the `<principals>` element appears first, so the `XMLUserManager` is the security manager.

### 3.4.3 Creating Your Own User Manager

If none of the user managers supplied by OC4J are suitable for your specific user authentication needs, then you can create your own user manager and configure OC4J to use it.

To create your own user manager, complete the following steps:

1. Write a custom user manager.

   Your custom user manager class must implement the `com.evermind.security.UserManager` interface. Table 3-2 describes the methods of this interface.

   Table 3-2 Methods of the UserManager Interface

   Method | Description
   --- | ---
   `void addDefaultGroup (java.lang.String name)` | Adds a group to the set of default groups, of which all users of the user manager are members. `java.lang.String name` - the name of the group being added to the default group
   `Group createGroup (java.lang.String name)` | Creates a new group. If the group already exists, a `java.lang.InstantiationException` is thrown. `java.lang.String name` - the name of the new group
   `User createUser (java.lang.String username, java.lang.String password)` | Creates a new user. `java.lang.String username` - the new user name `java.lang.String password` - the new user password
   `User getAdminUser()` | Returns the default admin user or `null` if there is none.
   `User getAnonymousUser()` | Returns the default anonymous user or `null` if none exists.
   `java.util.Set getDefaultGroups()` | Returns the set of default groups for the user manager.
   `Group getGroup(java.lang.String name)` | Returns the group with the specified name or `null` if none exists. `java.lang.String name` - the name of the specified group
   `int getGroupCount()` | Returns the number of users contained in the user manager. Throws `UnsupportedOperationException` if not supported.
   `java.util.List getGroups (int start,int max)` | Returns a list of groups (between the specified indexes) contained in the user manager. Throws `UnsupportedOperationException` if not supported.
   `UserManager getParent()` | Returns the parent manager of the user manager.
   `User getUser (java.lang.String username)` | Returns the user with the specified user name or `null` if there is no match.
   `User getUser (java.lang.String issuerDN, java.math.BigInteger serial)` | Returns the user associated with this certificate or `null` if either certificates are not supported or there is no user associated with this certificate.
   `User getUser (java.security.cert.X509Certificate certificate)` | Returns the user associated with this certificate or `null` if either certificates are not supported or there is no user associated with this certificate.
   `int getUserCount()` | Returns the number of users contained in this manager. Throws `UnsupportedOperationException` if not supported.
   `java.util.List getUsers (int start,int max)` | Returns a list of users (between the specified indexes) contained in this manager. Throws `UnsupportedOperationException` if not supported.
   `void init (java.util.Properties properties)` | Instantiates the user manager with the specified settings. Throws `java.lang.InstantiationException` if any errors occur.
   `boolean remove(Group group)` | Removes the specified group from the user manager and returns `true` if the operation is successful.
   `boolean remove(User user)` | Removes the specified user from the user manager and returns `true` if the operation is successful.
   `void setParent (UserManager parent)` | Sets the parent user manager if one exists. This method is called only on a nested user manager. A user manager can delegate work to its parent user manager.

2. Plug the user manager into your application.

   For a single application, specify the custom user manager in the `<user-manager>` element of the `orion-application.xml` file. For all applications in the server, specify the custom user manager in the `<user-manager>` element of the `config/application.xml` file.

3. Define your users and groups.

   See "Specifying Users and Groups".

4. Create security constraints in your Web application.

   See "Authorization".

Example 3-4 Using the DataSourceUserManager Class

The following example of the `DataSourceUserManager` class is a custom user manager and it implements the `UserManager` interface. Within its methods, the `DataSourceUserManager` class manages the users in a database specified by the `DataSource` interface.

To configure a custom user manager, you specific the classname in the `class` attribute of the `<user-manager>` element in either the global `application.xml` file or the `orion-application.xml` file. Then, you can specify input parameters and values through the `name`/`value` attributes of one or more `<property>` elements.

For our `DataSourceUserManager` example, it requires that the table name and columns are defined in the `<property>` element name/value pairs. This example sets up the following input parameters:

- Data source that specifies the database where the tables reside

- Table for user names and passwords

- Table for user and group association

A typical registration of the user manager for an application can be specified in `orion-application.xml`, as follows:

    <user-manager class="com.evermind.sql.DataSourceUserManager">
    	 <property name="dataSource" value="jdbc/OracleCoreDS" />
    	 <property name="table" value="j2ee_users" />
    	 <property name="usernameField" value="username" />
    	 <property name="passwordField" value="password" />
    	 <property name="groupMembershipTableName" value="second_table" />
    	 <property name="groupMembershipGroupFieldName" value="group" />
    	 <property name="groupMembershipUserNameFieldName" value="userId" />
    </user-manager>

The `<user-manager>` property elements define the input parameters into the `UserManager` class. It assumes that the tables that these refer to already exist in the database.

The user manager is a hierarchical implementation with a parent-child relationship. The parent of the `DataSourceUserManager` class is the default file-based `XMLUserManager` class, which uses the `principals.xml` user repository. However, you can change the parent with the `setParent()` method. The sample `DataSourceUserManager` class invokes `parent.getGroups()` to retrieve all the available groups from its parent, the `XMLUserManager`.

## 3.5 Confidentiality Through SSL

OC4J supports Secure Socket Layer (SSL) communication between the client and a standalone OC4J, using HTTPS.

The following sections document SSL in detail:

- Overview of Using SSL for OC4J Standalone

- Configuration of OC4J for SSL

- HTTPS Common Problems and Solutions

### 3.5.1 Overview of Using SSL for OC4J Standalone

The following sections describe security features and discuss how to use them with OC4J standalone:

- Overview of SSL Keys and Certificates

- Using Certificates with OC4J Standalone

#### 3.5.1.1 Overview of SSL Ke ys and Certificates

In SSL communication between two entities, each entity (or at least the server) has an associated public key and a private key. During communication, each entity uses its own private key, together with the public key of the other party, to ensure that they can communicate with each other. If one entity encrypts data using its private key, then the other party can decrypt the data by only by using the public key of the originating entity. If one entity encrypts data using the public key of the other party, then that party can decrypt the data only by using its own private key.

Each key is a number, with the private key of an entity being kept secret by that entity, and the public key of an entity being publicized to any other parties with which secure communication might be necessary.

A certificate is a digitally signed statement from a recognized issuer that verifies the public key of an entity. Such an issuer is referred to as a certificate authority (CA). An issued certificate is typically associated with a root certificate. This association, or "chaining", of certificates establishes a chain of trust. An issuer might have its own root certificate, and will chain any certificates it issues to its own root certificate.

Functionally, a certificate acts as a container for keys, holding private keys (as applicable), public keys, and associated signatures. A single certificate file can contain an entire chain of certificates.

A keystore is used for storage of certificates, including the certificates of all trusted parties. Through its keystore, an entity, such as OC4J, can authenticate itself to other parties.

A keystore is a `java.security.KeyStore` instance that you can create and manipulate using the `keytool` utility, provided with the Sun Microsystems JDK. Go to the following site for information about `keytool`:

    http://java.sun.com/j2se/1.3/docs/tooldocs/win32/keytool.html

During secure communication between the client and OC4J, the following functionality is executed:

- The link (all communications) between the two is encrypted.

- OC4J is authenticated to the client through a security challenge and response. A "secret key" is securely exchanged and used for the encryption of the link.

- Optionally, if OC4J is in client-authentication mode, the client is authenticated to OC4J.

#### 3.5.1.2 Using Certificates with OC4J Standalone

The steps for using keys and certificates for SSL communication in OC4J are as follows. These are server-level steps, typically executed prior to deployment of an application that will require secure communication, perhaps when you first set up OC4J.

1. Use `keytool` to generate a private key, public key, and unsigned certificate.You can place this information into either a new keystore or an existing keystore.

2. Obtain a signature for the certificate, using either of the following two approaches.

   - You can generate your own signature by using `keytool` to "self-sign" the certificate. This is appropriate if your only clients will trust you as, in effect, your own certificate authority.

   - You can obtain a signature from a recognized certificate authority through the following steps:

   1. Using the certificate from Step 1, use `keytool` to generate a certificate request, which is a request to have the certificate signed by a certificate authority.

   2. Submit the certificate request to a certificate authority.

   3. Receive the signature from the certificate authority and import it into the keystore, again using `keytool`. In the keystore, the signature will be matched with the associated certificate.

The process for requesting and receiving signatures is up to the particular certificate authority you use. You can go to the Web site of any certificate authority for information. Any browser should have a list of trusted certificate authorities. Here are the Web addresses for VeriSign and Thawte (acquired by VeriSign), for example:

    http://www.verisign.com/
    http://www.thawte.com/

In addition, Oracle provides a certificate authority, where each certificate is recognized only by Oracle applications. The Oracle Certificate Authority (OCA) allows customers to create and issue certificates for themselves and their users, although these certificates would likely be unrecognized outside a customer's organization without prior arrangements. See the Oracle Application Server Security Guide for information about OCA.

### 3.5.2 Configuration of OC4J for SSL

For secure communication between a client and OC4J, configuration is required on OC4J standalone. You are required to provide a certificate on the client-side only if you configure client-authentication.

In the `http-web-site.xml` file of OC4J (or other Web site XML file, as appropriate), you must specify appropriate SSL settings under the `<web-site>` element.

1. Turn on the `secure` flag to specify secure communication, as follows:

       <web-site ... protocol="http" secure="true" ... >
          ...
       </web-site>

   Setting `secure="true"` specifies that the HTTP protocol is to use an SSL socket.

2. Use the `<ssl-config>` subelement and its `keystore` and `keystore-password` attributes to specify the directory path and password for the keystore, as follows:

       <web-site ... secure="true" ... >
          ...
          <ssl-config keystore="path_and_file" keystore-password="pwd" />
       </web-site>

   The `<ssl-config>` element is required whenever the `secure` flag is set to `"true"`.

   The `path_and_file` value can indicate either an absolute or relative directory path and includes the file name.

   Note: You can hide the password through password indirection. See Oracle Application Server Containers for J2EE Security Guide for a description of password indirection.

3. Optionally, turn on the `needs-client-auth` flag, an attribute of the `<ssl-config>` element, to specify that client authentication is required, as follows:

       <web-site ... secure="true" ... >
          ...
          <ssl-config keystore="path_and_file" keystore-password="pwd"
                      needs-client-auth="true" />
       </web-site>

   This step sets up a mode where OC4J accepts or rejects a client entity for secure communication, depending on its identity. The `needs-client-auth` attribute instructs OC4J to request the client certificate chain upon connection. If the root certificate of the client is recognized, then the client is accepted.

   The keystore specified in the `<ssl-config>` element must contain the certificates of any clients that are authorized to connect to OC4J through HTTPS.

4. Optionally, specify each application in the Web site as shared. The `shared` attribute of the `<web-app>` element indicates whether multiple bindings (different Web sites, or ports, and context roots) can be shared. Supported values are `"true"` and `"false"` (default).

   Sharing implies the sharing of everything that makes up a Web application, including sessions, servlet instances, and context values. A typical use for this mode is to share a Web application between an HTTP site and an HTTPS site at the same context path, when SSL is required for some but not all of the communications. Performance is improved by encrypting only sensitive information, rather than all information.

   If an HTTPS Web application is marked as shared, then instead of using the SSL certificate to track the session, the cookie is used to track the session. This is beneficial in that the SSL certificiate uses 50K to store each certificate when tracking it, which sometimes results in an "out of memory" problem for the session before the session times out. This could possibly make the Web application less secure, but might be necessary to work around issues such as SSL session timeouts not being properly supported in some browsers.

5. Optionally, set the cookie domain if `shared` is true and the default ports are not used. When the client interacts with a Web server over separate ports, the cookie believes that each separate port denotes a separate Web site. If you use the default ports of 80 for HTTP and 443 for HTTPS, the client recognizes these as two different ports of the same Web site and creates only a single cookie. However, if you use non-default ports, the client does not recognize these ports as part of the same Web site and will create separate cookies for each port, unless you specify the cookie domain.

   Cookie domains track the client's communication across multiple servers within a DNS domain. If you use non-default ports for a shared environment with HTTP and HTTPS, set the `cookie-domain` attribute in the `<session-tracking>` element in the `orion-web.xml` file for the application. The cookie-domain attribute contains the DNS domain with at least two components of the domain name provided.

       <session-tracking cookie-domain=".oracle.com" />

Example 3-5 HTTPS Communication With Client Authentication

The following configures a Web site for HTTPS secure communication with client authentication:

    <web-site display-name="OC4J Web Site" protocol="http" secure="true" >
       <default-web-app application="default" name="defaultWebApp" />
       <access-log path="../log/default-web-access.log" />
       <ssl-config keystore="../keystore" keystore-password="welcome"
                  needs-client-auth="true" />
    </web-site>

Only the portions in bold are specific to security. The protocol value is always `"http"` for HTTP communication, whether or not you use secure communication. A protocol value of `http` with `secure="false"` indicates HTTP protocol; `http` with `secure="true"` indicates HTTPS protocol.

Then, configure the news application to accept both HTTP and HTTPS connections:

    <web-app application="news" name="news-web" root="/news" shared="true" />

This Web site uses the default port numbers for HTTP and HTTPS communication. If it did not, you would also add the `cookie-domain` attribute.

    <session-tracking cookie-domain=".oracle.com" />

For more information about elements and attributes of the `<web-site>`, `<web-app>`, and `<session-tracking>` elements, see the XML Appendix in the Oracle Application Server Containers for J2EE Servlet Developer's Guide.

Example 3-6 Creating an SSL Certificate and Configuring HTTPS

The following example uses `keytool` to create a test certificate and shows all of the XML configuration necessary for HTTPS to work. To create a valid certificate for use in production environments, see the `keytool` documentation.

1. Install the correct JDK

   Ensure that JDK 1.3.x is installed. This is required for SSL with OC4J. Set the JAVA_HOME to the JDK 1.3 directory. Ensure that the JDK 1.3.x `JAVA_HOME/bin` is at the beginning of your path. This may be achieved by doing the following:

   UNIX

       $ PATH=/usr/opt/java130/bin:$PATH
       $ export $PATH
       $ java -version
       java version "1.3.0"

   Windows

       set PATH=d:\jdk131\bin;%PATH%

   Ensure that this JDK version is set as the current version in your Windows registry. In the Windows Registry Editor under HKEY_LOCAL_MACHINE/SOFTWARE/JavaSoft/Java Development Kit, set 'CurrentVersion' to 1.3 (or later).

2. Request a certificate

   1. Change directory to `ORACLE_HOME/j2ee`

   2. Create a keystore with an RSA private/public keypair using the keytool command. In our example, we generate a keystore to reside in a file named 'mykeystore', which has a password of '123456' and is valid for 21 days, using the 'RSA' key pair generation algorithm with the following syntax:

       keytool -genkey -keyalg "RSA" -keystore mykeystore -storepass 123456 -validity 21

   Where:

   - the `keystore` option sets the filename where the keys are stored

   - the `storepass` option sets the password for protecting the keystore

   - the `validity` option sets number of days the certificate is valid

   The `keytool` prompts you for more information, as follows:

       keytool -genkey -keyalg "RSA" -keystore mykeystore -storepass 123456 -validity 21

       What is your first and last name?
         [Unknown]:  Test User
       What is the name of your organizational unit?
         [Unknown]:  Support
       What is the name of your organization?
         [Unknown]:  Oracle
       What is the name of your City or Locality?
         [Unknown]:  Redwood Shores
       What is the name of your State or Province?
         [Unknown]:  CA
       What is the two-letter country code for this unit?
         [Unknown]:  US
       Is <CN=Test User, OU=Support, O=Oracle, L=Reading, ST=Berkshire, C=GB> correct?
         [no]:  yes

       Enter key password for <mykey>
               (RETURN if same as keystore password):

   Note: To determine your 'two-letter country code', use the ISO country code list at the following URL: `http://www.bcpl.net/~jspath/isocodes.html.`

   The `mykeystore` file is created in the current directory. The default alias of the key is `mykey`.

3. If you do not have a `secure-web-site.xml` file, then copy the `http-web-site.xml` to `$J2EE_HOME/config/secure-web-site.xml.`

4. Edit `secure-web-site.xml` with the following elements:

   1. Add secure="true" to the `<web-site>` element, as follows:

          <web-site port="8888" display-name="Default Oracle Application Server Containers for J2EE Web Site" secure="true">

   2. Add the following new line inside the `<web-site>` element to define the keystore and the password.

          <ssl-config keystore="<Your-Keystore>" keystore-password="<Your-Password>" />

      Where `<Your-Keystore>` is the full path to the keystore and `<Your-Password>` is the keystore password. In our example, this is as follows:

          <!-- Enable SSL -->
          <ssl-config keystore="../../keystore" keystore-password="123456"/>

      Note: The keystore path is relative to where the XML file resides.

   3. Change the web-site port number, to use an available port. For example, the default for SSL ports is 443, so change the Web site port attribute to port="4443". To use the default of 443, you have to be a super user.

   4. Now save the changes to `secure-web-site.xml`.

5. If you did not have the `secure-web-site.xml` file, then edit `server.xml` to point to the `secure-web-site.xml` file.

   1. Uncomment or add the following line in the file `server.xml` so that the `secure-web-site`.xml file is read.

          <web-site path="./secure-web-site.xml" />

      Note: Even on Windows, you use a forward slash and not a back slash in the XML files.

   2. Save the changes to `server.xml`.

6. Stop and re-start OC4J to initialize the `secure-web-site.xml` file additions. Test the SSL port by accessing the site in a browser on the SSL port. If successful, you will be asked to accept the certificate, since it is not signed by an accepted authority.

When completed, OC4J listens for SSL requests on one port and non-SSL requests on another. You can disable either SSL requests or non-SSL requests, by commenting out the appropriate `*web-site.xml` in the `server.xml` configuration file.

    <web-site path="./secure-web-site.xml" /> - comment out this to remove SSL
    <default-site path="./http-web-site.xml" /> - comment out this to
                                                             remove non-SSL

#### 3.5.2.1 Requesting Client Authentication with OC4J Standalone

OC4J supports a "client-authentication" mode in which the server explicitly requests authentication from the client before the server will communicate with the client. In this case, the client must have its own certificate. The client authenticates itself by sending a certificate and a certificate chain that ends with a root certificate. OC4J can be configured to accept only root certificates from a specified list in establishing a chain of trust back to the client.

A certificate that OC4J trusts is called a trust point. This is the first certificate that OC4J encounters in the chain from the client that matches one in its own keystore. There are three ways to configure trust:

- The client certificate is in the keystore.

- One of the intermediate certificate authority certificates in the client's chain is in the keystore.

- The root certificate authority certificate in the client's chain is in the keystore.

OC4J verifies that the entire certificate chain up to and including the trust point is valid to prevent any forged certificates.

If you request client authentication with the `needs-client-auth` attribute, perform the following:

1. Decide which of the certificates in the client's chain is to be your trust point. Ensure that you either have control of the issue of certificates using this trust point or that you trust the certificate authority as an issuer.

2. Import the intermediate or root certificate in the server keystore as a trust point for authentication of the client certificate.

3. If you do not want OC4J to have access to certain trust points, make sure that these trust points are not in the keystore.

4. Execute the preceding steps to create the client certificate, which includes the intermediate or root certificate installed in the server. If you wish to trust another certificate authority, obtain a certificate from that authority.

5. Save the certificate in a file on the client.

6. Provide the certificate on the client initiation of the HTTPS connection.

   1. If the client is a browser, set the certificate in the client browser security area.

   2. If the client is a Java client, you must programmatically present the client certificate and the certificate chain when initiating the HTTPS connection.

### 3.5.3 HTTPS Common Problems and Solutions

The following errors may occur when using SSL certificates:

Keytool Error: java.security.cert.CertificateException: Unsupported encoding
  Cause: You cannot allow trailing whitespace in the keytool.
  Action: Delete all trailing whitespace. If the error still occurs, add a new line in your certificate reply file.

Keytool Error: KeyPairGenerator not available
  Cause: You are probably using a keytool from an older JDK.
  Action: Use the keytool from the latest JDK on your system. To ensure that you are using the latest JDK, specify the full path for this JDK.

Keytool Error: Failed to establish chain from reply
  Cause: The keytool cannot locate the root CA certificates in your keystore; thus, the keytool cannot build the certificate chain from your server key to the trusted root certificate authority.
  Action: Execute the following:

      keytool -keystore keystore -import -alias cacert -file cacert.cer (keytool -keystore keystore -import -alias intercert -file inter.cer)

  If you use an intermediate CA keytool, then execute the following:

      keystore keystore -genkey -keyalg RSA -alias serverkey keytool -keystore keystore -certreq -file my.host.com.csr

  Get the certificate from the Certificate Signing Request, then execute the following:

      keytool -keystore keystore -import -file my.host.com.cer -alias serverkey

IllegalArgumentException: Mixing secure and non-secure sites on the same ip + port
  Cause: You cannot configure SSL and non-SSL web-sites to listen on the same port and IP address.
  Action: Check to see that different ports are assigned within `secure-web-site.xml` and `http-web-site.xml` files.

Keytool does not work on HP-UX
  Cause: On HP-UX, it has been reported that the 'keytool' does not work with the RSA option.
  Action: Generate the key on another platform and FTP it to the HP-UX server.

#### 3.5.3.1 General SSL Debugging

You can get more debug information from the JSSE implementation. To get a list of options, start OC4J with:

    java -Djavax.net.debug=help -jar oc4j.jar

Or, if you want to turn on full verbosity, use:

    java -Djavax.net.debug=all -jar oc4j.jar

Both options will display:

- Browser request header

- Server HTTP header

- Server HTTP body (HTML served)

- Content length (before and after encryption)

- SSL version

For UNIX, you could use the startup scripts in NOTE 150215.1 'Scripts to Administer OC4J on Unix Platforms', and amend these.