Oracle® Application Server Containers for J2EE Standalone User's Guide
10g Release 2 (10.1.2) Part No. B14361-02 |
|
Previous |
Next |
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:
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.
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 theXMLUserManager 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.
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.
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.
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 thejazn-data.xml file.
|
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>
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.
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.
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:
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.
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
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);
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);
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:
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.
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>
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>
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
Note: The security role mapping layer, either defined in theprincipals.xml or jazn-data.xml file, is bypassed if the following conditions are true:
|
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. |
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. |
|
com.evermind.server. |
|
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:
The following sections describe how to configure each User Manager type:
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:
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:
For centralized storage of information in a directory. The user repository is OID.
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
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
).
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.
|
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.
|
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.
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:
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 |
---|---|
|
Adds a group to the set of default groups, of which all users of the user manager are members.
|
|
Creates a new group. If the group already exists, a
|
|
Creates a new user.
|
|
Returns the default admin user or |
|
Returns the default anonymous user or |
|
Returns the set of default groups for the user manager. |
|
Returns the group with the specified name or
|
|
Returns the number of users contained in the user manager. Throws |
|
Returns a list of groups (between the specified indexes) contained in the user manager. Throws |
|
Returns the parent manager of the user manager. |
|
Returns the user with the specified user name or |
|
Returns the user associated with this certificate or |
|
Returns the user associated with this certificate or |
|
Returns the number of users contained in this manager. Throws |
|
Returns a list of users (between the specified indexes) contained in this manager. Throws |
|
Instantiates the user manager with the specified settings. Throws |
|
Removes the specified group from the user manager and returns |
|
Removes the specified user from the user manager and returns |
|
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. |
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.
Define your users and groups.
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
.
OC4J supports Secure Socket Layer (SSL) communication between the client and a standalone OC4J, using HTTPS.
The following sections document SSL in detail:
The following sections describe security features and discuss how to use them with OC4J standalone:
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.
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.
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.
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:
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.
Submit the certificate request to a certificate authority.
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.
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.
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.
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. |
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.
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.
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.
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).
Request a certificate
Change directory to ORACLE_HOME/j2ee
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
.
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.
Edit secure-web-site.xml
with the following elements:
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">
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. |
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.
Now save the changes to secure-web-site.xml
.
If you did not have the secure-web-site.xml
file, then edit server.xml
to point to the secure-web-site.xml
file.
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. |
Save the changes to server.xml
.
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
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:
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.
Import the intermediate or root certificate in the server keystore as a trust point for authentication of the client certificate.
If you do not want OC4J to have access to certain trust points, make sure that these trust points are not in the keystore.
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.
Save the certificate in a file on the client.
Provide the certificate on the client initiation of the HTTPS connection.
If the client is a browser, set the certificate in the client browser security area.
If the client is a Java client, you must programmatically present the client certificate and the certificate chain when initiating the HTTPS connection.
The following errors may occur when using SSL certificates:
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
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.