Oracle8i Enterprise JavaBeans Developer's Guide and Reference
Release 3 (8.1.7)

Part Number A83725-01

Library

Solution Area

Contents

Index

Go to previous page Go to beginning of chapter Go to next page

Client-side Authentication

The Oracle data server is a secure server; a client application cannot access data stored in the database without first being authenticated by the database server. Oracle8i CORBA server objects and Enterprise JavaBeans execute in the database server. For a client to activate such an object and invoke methods on it, the client must authenticate itself to the server. The client authenticates itself when a CORBA or EJB object starts a new session. The following are examples of how each IIOP client must authenticate itself to the database:

The client authenticates itself by providing one of the following types:

Authentication type   Definition  

Certificates  

You can provide the user certificate, the Certificate Authority certificate (or a chain that contains both, including other identifying certificates), and a private key.  

Username and
password combination  

You can provide the username and password through either credentials or the login protocol. In addition, you can pass a database role to the server, along with the username and password.  

The type of client-side authentication can be determined by the server's configuration. If, within the SQLNET.ORA file, the SSL_CLIENT_AUTHENTICATION parameter is TRUE, the client must provide certificate-based authentication. If SSL_CLIENT_AUTHENTICATION is FALSE, the client authenticates itself with a username/password combination. If SSL_CLIENT_AUTHENTICATION is TRUE and the client provides a username/password, the connection handshake will fail.

The following table gives a brief overview of the options that the client has for authentication.

As the table demonstrates, most of the authentication options include setting an appropriate value in JNDI properties.

Using JNDI for Authentication

To set up client-side authentication using JNDI, you set the javax.naming.Context.SECURITY_AUTHENTICATION attribute to one of the following values:

Within each of these options, you choose to do one or more of the following:

Client authentication  

  • authenticate itself to the server using login protocol

  • authenticate itself to the server using straight username and password

  • authenticate itself to the server using SSL certificates

 

Server authentication  

  • authenticate itself to the client using SSL certificates

 

For information on how to implement each of these methods for client or server authentication, see the following sections:

Providing Username and Password for Client-Side Authentication

The client authenticates itself to the database server either through a username/password or by supplying appropriate certificates. The username/password can be supplied either through Oracle's login protocol or credentials over the SSL transport connection.

Username Sent by Setting JNDI Properties for the Login Protocol

A client can use the login protocol to authenticate itself to the Oracle8i data server. You can use the login protocol either with or without SSL encryption, because a secure handshaking encryption protocol is built in to the login protocol.

If your application requires an SSL connection for client-server data security, specify the SSL_LOGIN service context value for the SECURITY_AUTHENTICATION property that is passed when the JNDI initial context is obtained. The following example defines the connection to be SSL-enabled for the login protocol. Notice that the username and password are set.

Hashtable env = new Hashtable();
env.put(javax.naming.Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");
env.put(javax.naming.Context.SECURITY_PRINCIPAL, username);
env.put(javax.naming.Context.SECURITY_CREDENTIALS, password);
env.put(javax.naming.Context.SECURITY_AUTHENTICATION, ServiceCtx.SSL_LOGIN);
Context ic = new InitialContext(env);
...

If your application does not use an SSL connection, specify NON_SSL_LOGIN within the SECURITY_AUTHENTICATION parameter as shown below:


Note:

The login handshaking is secured by encryption, but the remainder of the client-server interaction is not secure.  


env.put(javax.naming.Context.SECURITY_AUTHENTICATION, ServiceCtx.NON_SSL_LOGIN);

When you specify values for all four JNDI Context variables--URL_PKG_PREFIXES, SECURITY_PRINCIPAL, SECURITY_CREDENTIALS, and SECURITY_AUTHENTICATION--the first invocation of the Context.lookup()method performs a login automatically.

If the client setting up the connection is not using JNDI look up because it already has an IOR, the user that gave them the IOR for the object should have also passed in a Login object that exists in the same session as the active object. You must provide the username and password in the authenticate method of the Login object, before invoking the methods on the active object.

Logging In and Out of the JServer Session

If the session owner wishes to exit the session, the owner can use the logout method of the LogoutServer object, which is pre-published as "/etc/logout". You use the LogoutServer object to exit the session. Only the session owner is allowed to logout. Any other owner receives a NO_PERMISSION exception.

The LogoutServer object is analogous to the LoginServer object, which is pre-published as "/etc/login". You can use the LoginServer object to retrieve the Login object, which is used to authenticate to the server. This is an alternative method to using the Login object within the JNDI lookup.

The following example shows how a client can authenticate using the LoginServer object and can exit the session through the LogoutServer object.

import oracle.aurora.AuroraServices.LoginServer;
import oracle.aurora.AuroraServices.LogoutServer;
...
// To log in using the LoginServer object
LoginServer loginServer = (LoginServer)ic.lookup(serviceURL + "/etc/login");
Login login = new Login(loginServer);
System.out.println("Logging in ..");
login.authenticate(user, password, null);
...
//To logout using the LogoutServer
LogoutServer logout = (LogoutServer)ic.lookup(serviceURL + "/etc/logout");
logout.logout();

Username Sent Implicitly by using Credentials

Using the ServiceCtx.SSL_CREDENTIAL authentication type means that the username, password, and, potentially, a role are passed to the server on the first request. Because this information is passed over an SSL connection, the password is encrypted by the transfer protocol, and there is no need for the handshaking that the Login protocol uses. This is slightly more efficient and is recommended for SSL connections.

Username Sent by Explicitly Activating a Login Object

You can explicitly create and populate a Login object for the database login. Typically, you would do this if you wanted to create and use more than a single session from a client. The following example shows a client creating and logging on to two different sessions. To do this, you must perform the following steps:

  1. Create the initial context.

  2. Perform a look up on a URL for the destination database.

  3. On this database service context, create two subcontexts--one for each session.

  4. Login to each session using a Login object, providing a username and password.


    Note:

    The username and password for both sessions are identical because the destination database is the same database. If the client were to connect to two different databases, the username and password may need to be different for logging on.  


    // Prepare a simplified Initial Context as we are going to do
    // everything by hand Hashtable env = new Hashtable (); env.put (Context.URL_PKG_PREFIXES, "oracle.aurora.jndi"); Context ic = new InitialContext (env); // Get a SessionCtx that represents a database instance ServiceCtx service = (ServiceCtx)ic.lookup (serviceURL); // Create and authenticate a first session in the instance. SessionCtx session1 = (SessionCtx)service.createSubcontext (":session1"); LoginServer login_server1 = (LoginServer)session1.activate ("etc/login"); Login login1 = new Login (login_server1); login1.authenticate (user, password, null); // Create and authenticate a second session in the instance. SessionCtx session2 = (SessionCtx)service.createSubcontext (":session2"); LoginServer login_server2 = (LoginServer)session2.activate ("etc/login"); Login login2 = new Login (login_server2); login2.authenticate (user, password, null); // Activate one Hello object in each session Hello hello1 = (Hello)session1.activate (objectName); Hello hello2 = (Hello)session2.activate (objectName);

Using Certificates for Client Authentication

Client authentication through certificates requires the client sending a certificate or certificate chain to the server; the server verifies that the client is truly who the client said it was and that it is trusted.


Note:

All certificates, trustpoints, and the private key should be in base-64 encoded format.  


You set up the client for certificate authentication through one of the following methods:

Specifying Certificates in a File

You can set up a file that contains the user certificate, the issuer certificate, the entire certificate chain, an encrypted private key, and the trustpoints. Once created, you can specify that the client use the file during connection handshake for client authentication.

  1. Create the client certificate file--This file can be created through an export feature in the Wallet Manager. The Oracle Wallet Manager has an option that creates this file. You must populate a wallet using the Wallet Manager before requesting that the file is created.

    After you create a valid wallet, bring up the Wallet Manager and perform the following:

    • From the menu bar pull down, click on Operations > Export Wallet.

    • Within the filename field, enter the name that you want the certificate file known as.

    This creates a base-64 encoded file that contains all certificates, keys, and trustpoints that you added within your wallet. For information on how to create the wallet, see the Oracle Advanced Security Administrator's Guide.

  2. Specify the client certificates file for the connection--Within the client code, set the SECURITY_AUTHENTICATION property to ServiceCtx.SSL_CLIENT_AUTH. Provide the appropriate certificates and trustpoints for the server to authenticate against. Specify the filename and decrypting key in the JNDI properties, as follows:

    Values   Set in JNDI Property  

    Name of the certificate file  

    SECURITY_PRINCIPAL  

    Key for decrypting the private key  

    SECURITY_CREDENTIAL  

    The following code is an example of how to set up the JNDI properties to define the client certificate file:

    Hashtable env = new Hashtable();
    env.put(javax.naming.Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");
    env.put(javax.naming.Context.SECURITY_PRINCIPAL, <filename>);
    env.put(javax.naming.Context.SECURITY_CREDENTIAL, <decrypting_key>);
    env.put(javax.naming.Context.SECURITY_AUTHENTICATION, 
    ServiceCtx.SSL_CLIENT_AUTH); Context ic = new InitialContext(env); ...

    For example, if your decrypting key is welcome12 and the certificate file is credsFile, the following two lines would specify these values within the JNDI context:

    env.put(Context.SECURITY_CREDENTIALS, "welcome12");
    env.put(Context.SECURITY_PRINCIPAL, "credsFile");
    

Specifying Certificates in Individual JNDI Properties

You can provide each certificate, private key, and trust point programmatically, by setting each item individually within JNDI properties. Once you populate the JNDI properties with the user certificate, issuer (Certificate Authority) certificate, encrypted private key, and trust points, they are used during connection handshake for authentication. To identify client-side authentication, set the SECURITY_AUTHENTICATION property to serviceCtx.SSL_CLIENT_AUTH.


Note:

Only a single issuer certificate can be set through JNDI properties.  


You can choose any method for setting up your certificates within the JNDI properties. All authorization information values must be set up before initializing the context.

The following example declares the certificates as a static variable. However, this is just one of many options. Your certificate must be base-64 encoded. For example, in the following code, the testCert_base64 is a base-64 encoded client certificate declared as a static variable. The other variables for CA certificate, private key, and so on, are not shown, but they are defined similarly.


Note:

When setting individual certificates as static variables, any certificates for Oracle8i parties do not have any separators. However, if you are setting a certificate for a Visigenic ORB (as the client callback object does in a callback scenario), the certificate must be delineated by "BEGIN CERTIFICATE" and "END CERTIFICATE" identifying lines. See the Visigenic documentation for the format of these strings.  


final private static String testCert_base64 =
  "MIICejCCAeOgAwIBAgICAmowDQYJKoZIhvcNAQEEBQAwazELMAkGA1UEBhMCVVMx" +
  "DzANBgNVBAoTBk9yYWNsZTEoMCYGA1UECxMfRW50ZXJwcmlzZSBBcHBsaWNhdGlv" +
  "biBTZXJ2aWNlczEhMB8GA1UEAxMYRUFTUUEgQ2VydGlmaWNhdGUgU2VydmVyMB4X" +
  "DTk5MDgxNzE2MjIxMloXDTAwMDIxMzE2MjIxMlowgYUxCzAJBgNVBAYTAlVTMRsw" +
  "GQYDVQQKExJPcmFjbGUgQ29ycG9yYXRpb24xPDA6BgNVBAsUMyoqIFNlY3VyaXR5" +
  "IFRFU1RJTkcgQU5EIEVWQUxVQVRJT04gT05MWSB2ZXJzaW9uMiAqKjEbMBkGA1UE" +
  "AxQSdGVzdEB1cy5vcmFjbGUuY29tMHwwDQYJKoZIhvcNAQEBBQADawAwaAJhANG1" +
  "Kk2K7uOOtI/UBYrmTe89LVRrG83Eb0/wY3xWGelkBeEUTwW57a26u2M9LZAfmT91" +
  "e8Afksqc4qQW23Sjxyo4ObQK3Kth6y1NJgovBgfMu1YGtDHaSn2VEg8p58g+nwID" +
  "AQABozYwNDARBglghkgBhvhCAQEEBAMCAMAwHwYDVR0jBBgwFoAUDCHwEuJfIFXD" +
  "a7tuYNO8bOw1EYwwDQYJKoZIhvcNAQEEBQADgYEARC5rWKge5trqgZ18onldinCg" +
  "Fof6D/qFT9b6Cex5JK3a2dEekg/P/KqDINyifIZL0DV7z/XCK6PQDLwYcVqSSK/m" +
  "487qjdH+zM5X+1DaJ+ROhqOOX54UpiAhAleRMdLT5KuXV6AtAx6Q2mc8k9bzFzwq" +
  "eR3uI+i5Tn0dKgxhCZU=\n";

Hashtable env = new Hashtable();
env.put(Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");
env.put(Context.SECURITY_AUTHENTICATION, ServiceCtx.SSL_CLIENT_AUTH);
//decrypting key
env.put(Context.SECURITY_CREDENTIALS, "welcome12");

// you may also set the certificates individually, as shown bellow.
//User certificate
env.put(ServiceCtx.SECURITY_USER_CERT, testCert_base64);
//Certificate Authority's certificate
env.put(ServiceCtx.SECURITY_CA_CERT, caCert_base64);
//Private key
env.put(ServiceCtx.SECURITY_ENCRYPTED_PKEY, encryptedPrivateKey_base64);
// setup the trust point
env.put(ServiceCtx.SECURITY_TRUSTED_CERT, trustedCert);

Context ic = new InitialContext(env);

Specifying Certificates using AuroraCertificateManager

CORBA clients that do not use JNDI can use AuroraCertificateManager for setting the user and issuer certificates, the encrypted private key, and the trust points.

AuroraCertificateManager maintains certificates for your application. For the certificates to be passed on the SSL handshake for the connection, you must set the certificates before an SSL connection is made. Setting up a certificate in this manner is only required if the following is true:

AuroraCertificateManager Class

The methods offered by this object allow you to:

Invoking the ORB.resolve_initial_references method with the parameter SSLCertificateManager will return an object that can be narrowed to a AuroraCertificateManager. Example 6-1 shows a code example of the following methods.

addTrustedCertificate

This method adds the specified certificate as a trusted certificate. The certificate must be in DER encoded format. The client adds trustpoints through this method for server-side authentication.

When your client wants to authenticate a server, the server sends its certificate chain to the client. You might not want to check every certificate in the chain. For example, you have a chain composed of the following certificates: Certificate Authority, enterprise, business unit, a company site, and a user. If you trust the company site, you would check the user's certificate, but you might stop checking the chain when you get to the company site's certificate, because you accept the certificates above the company sites in the hierarchical chain.

Syntax

void addTrustedCertificate(byte[] derCert);

Parameter   Description  

derCert  

The DER encoded byte array containing the certificate.  

requestClientCertificate

This method is invoked by servers that wish to require certificates from client applications. This method is not intended for use by client applications.


Note:

The requestClientCertificate method is not currently required, because the SQLNET.ORA and LISTENER.ORA configuration parameter SSL_CLIENT_AUTHENTICATION performs its function.  


Syntax

void requestClientCertificate(boolean need);

Parameter   Description  

need  

If true, the client must send a certificate for authentication. If false, no certificate is requested from the client.  

setCertificateChain

This method sets the certificate chain for your client application or server object and can be invoked by clients or by servers. The certificate chain always starts with the Certificate Authority certificate. Each subsequent certificate is for the issuer of the preceding certificate. The last certificate in the chain is the certificate for the user or process.

Syntax

void setCertificateChain(byte[][] derCertChain)

Parameter   Description  

derCertChain  

A byte array containing an array of certificates.  

setEncryptedPrivateKey

This method sets the private key for your client application or server object. You must specify the key in PKCS5 or PKCS8 format.

Syntax

void setEncryptedPrivateKey(byte[] key, String password);

Parameter   Description  

key  

The byte array that contains the encrypted private key.  

password  

A string containing a password for decrypting the private key.  

setProtocolVersion

This method sets the SSL protocol version that can be used for the connection. A 2.0 Client trying to establish an SSL connection with a 3.0 Server will fail and the converse. We recommend using Version_Undetermined, because it lets the peers establish an SSL connection whether they are using the same protocol version or not. SSL_Version_Undetermined is the default value.

Syntax

void setProtocolVersion(int protocolVersion);

Parameter   Description  

protocolVersion  

The protocol version being specified. The value you supply is defined in oracle.security.SSL.OracleSSLProtocolVersion. This class defines the following values:

  • SSL_Version_Undetermined: Version is undetermined. This is used to connect to SSL 2.0 and SSL 3.0 peers. This is the default version.

  • SSL_Version_3_0_With_2_0_Hello: Not supported.

  • SSL_Version_3_0: Used to connect to 3.0 peers only.

  • SSL_Version_2_0: Not supported.

 

Example 6-1 Setting SSL Security Information Using AuroraCertificateManager

This example does the following:

  1. Retrieve the AuroraCertificateManager.

  2. Initialize this client's SSL information:

    1. Set the certificate chain through setCertificateChain.

    2. Set the trustpoint through addTrustedCertificate.

    3. Set the private key through setEncryptedPrivateKey.

      // Get the certificate manager
      AuroraCertificateManager cm = AuroraCertificateManagerHelper.narrow(
      	orb.resolve_initial_references("AuroraSSLCertificateManager"));
      
      BASE64Decoder decoder = new BASE64Decoder();
      byte[] userCert = decoder.decodeBuffer(testCert_base64);
      byte[] caCert = decoder.decodeBuffer(caCert_base64);
      
      // Set my certificate chain, ordered from CA to user.
      byte[][] certificates = {
              caCert, userCert
      };
      cm.setCertificateChain(certificates);
      cm.addTrustedCertificate(caCert);
      
      // Set my private key.
      byte[] encryptedPrivateKey =
      decoder.decodeBuffer(encryptedPrivateKey_base64);
      
      cm.setEncryptedPrivateKey(encryptedPrivateKey, "welcome12");
      


Go to previous page
Go to beginning of chapter
Go to next page
Oracle
Copyright © 1996-2000, Oracle Corporation.

All Rights Reserved.

Library

Solution Area

Contents

Index