Archive for the ‘Oracle Application Server’ Category

OC4J Instance Startup Dependencies

Saturday, August 22nd, 2009

(Originally posted on “old” Jason Bennett’s Developer Corner, Sunday, August 05, 2007)

OracleAS 10g can be configured to allow startup dependencies between OC4J instances.  In other words, OC4J instance OC4J_B cannot start until OC4J instance OC4J_A has started.  This is along the same lines as one MS Windows service being dependant on another at startup.    This is useful (and necessary) if OC4J instance OC4J_A contains services that provide some sort of critical data that some application in OC4J instance OC4J_B needs as part of its initialization.  The only catch to this is that the OC4J instances can’t be located within the same ias-component.  An ias-component consists of one or more process-types.  An example of a process-type would be an OC4J instance.  For example, every time you create a new OC4J instance using dcmctl or OracleAS 10g Enterprise Manager, it is placed under the ias-component called “OC4J”.  Other examples of common ias-components are: LogLoader, dcm-daemon,  HTTP_Server,  and WebCache.  Executing the command “opmnctl status” will give a listing of each ias-component and the name of each process-type associated with it.

The easiest way to create a new ias-component and associated OC4J instance (or process-type) with a dependency on another OC4J instance is:

1. Create a new OC4J instance (process-type) using dcmctl or OracleAS Enterprise Manager (skip this step if you plan on moving an existing OC4J instance).
2. Open the opmn.xml file and create a new ias-component entry (make sure you back-up the existing file and shutdown opmn before doing this !)

<ias-component id=”My Custom Component”>

</ias-component>

3. Locate the OC4J instance you created in step-one (it should be under the “OC4J” ias-component).  Cut the entire tag set defining the OC4J instance (process-type) and paste it into your new ias-component (You can also do this with an existing OC4J instance):

<ias-component id=” My Custom Component “>
<process-type id=”OC4J_B” module-id=”OC4J”>
<module-data>
<category id=”start-parameters”>
<data id=”java-options” value=”-server -Djava.security.policy= /app/oracle/product/10.1.2/midtier/j2ee/ OC4J_B /config/java2.policy -Djava.awt.headless=true”/>
<data id=”oc4j-options” value=”-properties”/>
</category>
<category id=”stop-parameters”>
<data id=”java-options” value=”-Djava.security.policy= /app/oracle/product/10.1.2/midtier/j2ee/ OC4J_B /config/java2.policy -Djava.awt.headless=true”/>
</category>
</module-data>
<start timeout=”900″ retry=”2″/>
<stop timeout=”120″/>
<restart timeout=”720″ retry=”2″/>
<port id=”ajp” range=”12501-12600″/>
<port id=”rmi” range=”12401-12500″/>
<port id=”jms” range=”12601-12700″/>
<process-set id=”default_island” numprocs=”1″/>
</process-type>
</ias-component>

4.  To define the dependency between the OC4J instance defined under your new ias-component and another OC4J instance defined under a different ias-component, you need to add a dependency definition under the ias-component tag:

<ias-component id=” My Custom Component “>
<dependencies>
<managed-process ias-component=”OC4J” process-type=”OC4J_A” process-set=”default_island” autostart=”true” />
</dependencies>

<process-type id=”OC4J_B” module-id=”OC4J”>
<module-data>
<category id=”start-parameters”>
<data id=”java-options” value=”-server -Djava.security.policy= /app/oracle/product/10.1.2/midtier/j2ee/ OC4J_B /config/java2.policy -Djava.awt.headless=true”/>
<data id=”oc4j-options” value=”-properties”/>
</category>
<category id=”stop-parameters”>
<data id=”java-options” value=”-Djava.security.policy= /app/oracle/product/10.1.2/midtier/j2ee/ OC4J_B /config/java2.policy -Djava.awt.headless=true”/>
</category>
</module-data>
<start timeout=”900″ retry=”2″/>
<stop timeout=”120″/>
<restart timeout=”720″ retry=”2″/>
<port id=”ajp” range=”12501-12600″/>
<port id=”rmi” range=”12401-12500″/>
<port id=”jms” range=”12601-12700″/>
<process-set id=”default_island” numprocs=”1″/>
</process-type>
</ias-component>

5. Save the opmn.xml file and start up opmn and all of its processes.
That’s all there is to it!  Now OC4J_B will not start until OC4J_A has started.

Passing Mod_Plsql Basic Authentication Credentials Across Applications

Saturday, August 22nd, 2009

(Originally posted on the “old” Jason Bennett’s Developer Corner, Saturday, June 23, 2007)

I was recently tasked with the “seamless” integration of a large Web PL/SQL based application and newer J2EE application. The older application uses a mod_plsql DAD to authenticate users (using the Basic Authentication method), and the newer application built with Oracle ADF and JSF. Each user has a separate database account, and application security is database role based. The problem: How do I pass the users credentials (basically their database login information) to the J2EE application in order to create a user specific database connection? The user accesses the new application from a hyperlink on the existing application’s main menu. It sounds easy enough. Simply write a servlet filter to capture the “AUTHORIZATION” HTTP header and decode the credentials, right? Wrong. Since the J2EE application in seemingly different domain or session space, the “AUTHORIZATION” header is not passed. By the way, SSO and other “new” technologies were not currently available. So, how do we get around the cross domain/session space issue? It turns out to be fairly simple. Both applications are served through the same Apache web-server (OracleAS 10g R1), allowing us to use a very simple method that leverages mod_rewrite (pre-installed and configured with OracleAS 10g).

The Method …

The method uses the following three steps:

1. The URL from the older (calling) application to the newer (target) application has to look as if it is using the mod_plsql DAD. This gives the false impression that the target of the URL is in the same domain/session space as the current application. The URL would look something like: http://servername:7778/<;dad name>/application.do. This basically fools the browser into passing the domain/session space HTTP headers (specifically the “AUTHORIZATION” header) along with the request.

2. In the httpd.conf file (or a separate include .conf file) associated with your Apache instance, place a mod_rewrite directive like this one:

RewriteRule ^(//application.do)$ //application.do [PT]

3. In the Servlet Filter (or whatever portion of your application that can capture incoming HTTP request headers), get the value of the “AUTHORIZATION” HTTP request header. Here is an example of how this code looks using Java: String credentials = req.getHeader(“AUTHORIZATION”); (req is an instance of HttpServletRequest).

Decrypting the Credentials

After you get the credentials using the three step method above, you need to decrypt them. The value of the “AUTHORIZATION” HTTP header will be a string encoded using the base64 encoding method. It will look something like this:

Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== ( )

Decrypting the string is pretty simple using a base64 decoder such as Sun’s sun.misc.BASE64Decoder class. Before decrypting the string, we need parse out the credential portion of the string (i.e. we need to remove the “Basic” portion of the string). When decrypted, the above string will look like this:

Aladdin:open sesame (:
)

Once we get the credentials decrypted, simply parse the string to obtain the username and password. The following is a simple Java class that will aid in decrypting and returning the username and password:

import java.util.StringTokenizer;
import sun.misc.BASE64Decoder;

public class BasicAuthDecoder {

private String authType = “Basic”;

private String codedCredential = null;
private String username = null;
private String password = null;

public BasicAuthDecoder(String rawCredentialString) {

if (rawCredentialString != null){

setCodedCredential(rawCredentialString);

decodeCredentials();

}

}

private void setCodedCredential(String rawCredentialString){

StringTokenizer authTokens = new StringTokenizer(rawCredentialString);

if (authTokens.hasMoreTokens()){

if (authTokens.nextToken().equalsIgnoreCase(authType)){

codedCredential = authTokens.nextToken();

}

}

}

private void decodeCredentials(){

String decodedCredentialString = null;

try{

BASE64Decoder decoder = new BASE64Decoder();
decodedCredentialString = new String(decoder.decodeBuffer(codedCredential));

StringTokenizer authTokens = new StringTokenizer(decodedCredentialString,”:”);

if (authTokens.hasMoreTokens()){

username = authTokens.nextToken();
password = authTokens.nextToken();

}

}catch(Exception e){
System.err.println(“Error decoding user credentials “+e.getMessage());
}

}

public String getUsername(){

return username;

}

public String getPassword(){

return password;

}

}