Jason Bennett's Developer Corner

 






Click to see the XML version of this web page.

>


View David Jason Bennett's profile on LinkedIn

 

 

A Little About Jason Bennett ...

I've had an interest in publishing technical articles and HELPFUL code for a few years.  I am (by trade and hobby) a developer who specializes in Oracle technologies and web based architectures.  I have been an employee of both TUSC and Oracle Corporation.  My intent here is to share my ideas and coding experiences with the developer community as a whole.  As with all developers some of my ideas are great and some of them are ....  well you know.  Anyway, I hope you find something here that will aid in your endeavor, or spark a new idea. 

I am more than happy to assist with technical issues and will even write a little code if need be. If you find something on the site that is really useful and you'd like to make a contribution (absolutely up to you and absolutely not required), just click the "Make a Donation" button on the left!

Good luck and good coding !




  Saturday, June 23, 2007


Passing Mod_Plsql Basic Authentication Credentials Across Applications

 

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 ^(/<dadname>/application.do)$ /<context root>/application.do [PT]

 

  1. 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== (<Encryption type> <Credentials>)

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 (<username>:<password>)

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;

    }

}

 


1:09:54 PM    

Click here to visit the Radio UserLand website. © Copyright 2008Jason Bennett.
Last update: 8/28/2008; 9:46:38 PM.

June 2007
Sun Mon Tue Wed Thu Fri Sat
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
May   Jul