Oracle8i Enterprise JavaBeans Developer's Guide and Reference Release 3 (8.1.7) Part Number A83725-01 |
|
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:
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.
To set up client-side authentication using JNDI, you set the javax.naming.Context.SECURITY_AUTHENTICATION
attribute to one of the following values:
ServiceCtx.NON_SSL_LOGIN
--A plain IIOP connection is used. Because SSL is not used, all data flowing over the line is not encrypted. Thus, to protect the password, the client uses the login protocol to authenticate itself. In addition, the server does not provide SSL certificates to the client to identify itself.
ServiceCtx.SSL_LOGIN
--An SSL-enabled IIOP connection is used. All data flowing over the transport is encrypted. If you do not want to provide a certificate for the client authentication, use the login protocol to provide the username and password.
Because this is an SSL connection, the server sends its certificate identity to the client. The client is responsible for verifying the server's certificate, if interested, for server authentication. Optionally, the client can set up trust points for the server's certificate to be verified against.
ServiceCtx.SSL_CREDENTIAL
--An SSL-enabled IIOP connection is used. All data flowing over the transport is encrypted. The client provides the username and password without using the login protocol for client authentication to the server. The username and password are automatically passed to the server in a security context, on the first message.
The server provides its certificate identity to the client. The client is responsible for verifying the server's certificate, if interested, for server authentication.
ServiceCtx.SSL_CLIENT_AUTH
--An SSL-enabled IIOP connection is used. All data flowing over the transport is encrypted. The client provides appropriate certificates for client-side authentication to the server. In addition, the server provides its certificate identity to the client. If interested, the client is responsible for authorizing the server's certificate.
demo/examples/corba/session/sharedsession
example for more information. The username and password in the initial context environment are automatically passed as parameters to the login object's authenticate()
method.
Within each of these options, you choose to do one or more of the following:
Client authentication |
|
Server authentication |
For information on how to implement each of these methods for client or server authentication, see the following sections:
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.
SECURITY_AUTHENTICATION
to ServiceCtx.SSL_LOGIN
or ServiceCtx.NON_SSL_LOGIN
.
SECURITY_AUTHENTICATION
to serviceCtx.SSL_CREDENTIAL
.
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:
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.
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();
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.
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:
// 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);
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.
You set up the client for certificate authentication through one of the following methods:
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.
After you create a valid wallet, bring up the Wallet Manager and perform the following:
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.
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 |
|
Key for decrypting the private key |
|
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.S
SL_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");
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
.
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.
final private static StringtestCert_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);
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
if client-side authentication is required, and the client does not want to use JNDI properties for setting certificates.
AuroraCertficateManager
if it is executing a callout or a callback. The typical server-side authentication for a simple client/server exchange is taken care of by the database wallet. However, if this server intends to act as a client by executing a callout or callback, it needs to set certificates identifying itself; it cannot use the database certificate that is contained in the wallet.
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.
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. |
This method is invoked by servers that wish to require certificates from client applications. This method is not intended for use by client applications.
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. |
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. |
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. |
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 |
This example does the following:
AuroraCertificateManager
.
setCertificateChain
.
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");
|
Copyright © 1996-2000, Oracle Corporation. All Rights Reserved. |
|