Skip Headers

Oracle® Application Server Single Sign-On Application Developer's Guide
10g (9.0.4)

Part Number B10852-01
Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Go to previous page Go to next page

2
Developing Applications for Single Sign-On

This chapter explains how to develop applications to work with mod_osso. The chapter contains the following topics:

Protecting Applications Using mod_osso: Two Methods

mod_osso redirects the user to the single sign-on server only if the URL you request is configured to be protected. You can secure URLs in one of two ways: statically or dynamically. Static directives simply protect the application, ceding control over user interaction to mod_osso. Dynamic directives not only protect the application, they also enable it to regulate user access.

This section contains the following topics:

Protecting URLs Statically

You can statically protect URLs with mod_osso by applying directives to the mod_osso.conf file. In the example that follows, a directory named /private, located just below the Oracle HTTP Server document root, is protected by this directive:

<IfModule mod_osso.c>

  <Location /private>
    AuthType Basic
    require valid-user
  </Location>

</IfModule>

After making the entry, populate the directory with pages and then test them. For example:

http://host:port/private/helloworld.html

Finally, restart the Oracle HTTP Server:

$ORACLE_HOME/opmn/bin/opmnctl restartproc type=ohs

Protecting URLs with Dynamic Directives

Dynamic directives are HTTP response headers that have special error codes that enable an application to request granular functionality from the single sign-on system without having to implement the intricacies of the single sign-on protocol. Upon receiving a directive as part of a simple HTTP response from the application, mod_osso creates the appropriate single sign-on protocol message and communicates it to the single sign-on server.

OracleAS release 9.0.4 supports dynamic directives for Java servlets and JSPs. The product does not currently support dynamic directives for PL/SQL applications.

Table 2-1 lists commonly requested dynamic directives.

Table 2-1 Commonly Requested Dynamic Directives
Directive Status Code Headers

Request Authentication

401, 499

-

Request Forced Authentication

499

Osso-Paranoid: true

Single Sign-Off

470

Osso-Return-URL

This is the URL to return to after single sign-off is complete

Developing Applications Using mod_osso

This section explains how to write and enable applications using mod_osso. The section contains the following topics:

Developing Statically Protected PL/SQL Applications

What follows is an example of a simple mod_osso-protected application. This application logs the user in to the single sign-on server, displays user information, and then logs the user out of both the application and the single sign-on server.

Use the following steps to write and enable a PL/SQL application using mod_osso.

  1. Create the schema where application procedure will be loaded.

    sqlplus sys/sys_password as sysdba
    create user schema_name identified by schema_password;
    grant connect,  resource to schema_name;
    
  2. Load the following procedure into the schema and grant the public access to the procedure:

    create or replace procedure show_user_info
     is
     begin
        begin
            htp.init;
         exception
             when others then null;
         end;
         htp.htmlOpen;
         htp.bodyOpen;
         htp.print('<h2>Welcome to Oracle Single Sign-On</h2>');
         htp.print('<pre>');
         htp.print('Remote user: '
            || owa_util.get_cgi_env('REMOTE_USER'));
         htp.print('User DN: '
            || owa_util.get_cgi_env('Osso-User-Dn'));
         htp.print('User Guid: '
            || owa_util.get_cgi_env('Osso-User-Guid'));
         htp.print('Subscriber: '
            || owa_util.get_cgi_env('Osso-Subscriber'));
         htp.print('Subscriber DN: '
            || owa_util.get_cgi_env('Osso-Subscriber-Dn'));
         htp.print('Subscriber Guid: '
            || owa_util.get_cgi_env('Osso-Subscriber-Guid'));
         htp.print('</pre>');
         htp.print('<a href=/osso_logout?'
            ||'p_done_url=http://my.oracle.com>Logout</a>');
    
         htp.bodyClose;
         htp.htmlClose;
    end show_user_info;
    /
    show errors;
    
    grant execute on show_user_info to public;
    
    
  3. Create a database access descriptor (DAD) for the application in the dads.conf file, located at $ORACLE_HOME/Apache/modplsql/conf:

    <Location /pls/DAD_name>
           SetHandler pls_handler
           Order deny,allow
           AllowOverride None
           PlsqlDatabaseConnectString    hostname:port:SID
           PlsqlDatabasePassword         schema_password
           PlsqlDatabaseUsername         schema_name
           PlsqlDefaultPage              schema_name.show_user_info
           PlsqlDocumentTablename        schema_name.wwdoc_document
           PlsqlDocumentPath             docs
           PlsqlDocumentProcedure        schema_name.wwdoc_process.process_
                                           download
           PlsqlAuthenticationMode       Basic
           PlsqlPathAlias                url
           PlsqlPathAliasProcedure       schema_name.wwpth_api_alias.process_
                                           download
           PlsqlSessionCookieName        schema_name
           PlsqlCGIEnvironmentList       OSSO-USER-DN
           PlsqlCGIEnvironmentList       OSSO-USER-GUID
           PlsqlCGIEnvironmentList       OSSO-SUBSCRIBER
           PlsqlCGIEnvironmentList       OSSO-SUBSCRIBER-DN
           PlsqlCGIEnvironmentList       OSSO-SUBSCRIBER-GUID
    </Location>
    
    
    
  4. Protect the application DAD by entering the following lines in the mod_osso.conf file:

    <Location /pls/DAD_name>
      require valid-user
      authType Basic
    </Location>
    


    Note:

    The assumption here is that mod_osso is already configured for single sign-on. This step is performed when OracleAS is installed.


  5. Restart the Oracle HTTP Server that will be used by this application:

    $ORACLE_HOME/opmn/bin/opmnctl restartproc type=ohs
    
    
  6. To test whether the newly created functions and procedures are protected by mod_osso, try to access them from a browser:

    http://host:port/pls/DAD/schema_name.show_user_info
    
    

    Selecting the URL should invoke the single sign-on login page if mod_osso.conf has been configured properly and mod_osso is registered with the single sign-on server.

Developing Statically Protected Java Applications

Use the following steps to write and enable a servlet or JSP application using mod_osso:

  1. Write the JSP or servlet. Like the PL/SQL application example immediately preceding, the simple servlet that follows logs the user in, displays user information, and then logs the user out.

    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
    
    /**
     * Example servlet showing how to get the SSO User information
     */
    
    public class SSOProtected extends HttpServlet
    {
      
        public void service(HttpServletRequest request,
                          HttpServletResponse response)
            throws IOException, ServletException
        {
            response.setContentType("text/html");
    
            // Show authenticated user informationsingle sign-on
            PrintWriter out = response.getWriter();
            out.println("<h2>Welcome to Oracle Single Sign-On</h2>");
            out.println("<pre>");
            out.println("Remote user: "
                + request.getRemoteUser());
            out.println("Osso-User-Dn: "
                +  request.getHeader("Osso-User-Dn"));
            out.println("Osso-User-Guid: "
                +  request.getHeader("Osso-User-Guid"));
            out.println("Osso-Subscriber: "
                +  request.getHeader("Osso-Subscriber"));
            out.println("Osso-User-Dn: "
                +  request.getHeader("Osso-User-Dn"));
            out.println("Osso-Subscriber-Dn: "
                +  request.getHeader("Osso-Subscriber-Dn"));
            out.println("Osso-Subscriber-Guid: "
                +  request.getHeader("Osso-Subscriber-Guid"));
            out.println("Lang/Territory: "
                + request.getHeader("Accept-Language"));
            out.println("</pre>");
            out.println("<a href=/osso_logout?"
                +"p_done_url=http://my.oracle.com>Logout</a>");
    
    
  2. Protect the servlet by entering the following lines in the mod_osso.conf file:

    <Location /servlet>
       require valid-user
       authType Basic
    </Location>
    
    
  3. Deploy the servlet; then restart the Oracle HTTP Server and OC4J:

    $ORACLE_HOME/opmn/bin/opmnctl restartproc type=ohs
    $ORACLE_HOME/opmn/bin/opmnctl stopproc type=oc4j
    $ORACLE_HOME/opmn/bin/opmnctl startproc type=oc4j
    
    
  4. Test the servlet by trying to access it from the browser. Selecting the URL should invoke the login page.

    The process is this: when you try to access the servlet from the browser, you are redirected to the single sign-on server for authentication. Next you are redirected back to the servlet, which displays user information. You may then select the logout link to log out of the application as well as the single sign-on server.

Developing Java Applications That Use Dynamic Directives

Applications that use dynamic directives require no entry in mod_osso.conf because mod_osso protection is written directly into the application as one or more dynamic directives. The servlets that follow show how such directives are incorporated. Like their "static" counterparts, these sample "dynamic" applications generate user information.

This section covers the following topics:

Java Example #1: Simple Authentication

Java Example #2: Single Sign-Off

Java Example #3: Forced Authentication

A Word About Non-GET Authentication

The first page of a mod_osso-protected application must be a URL that uses the GET authentication method. If the POST method is used, the data that the user provides when logging in is lost during redirection to the single sign-on server. When deciding whether to enable the global user inactivity timeout, please note that users are redirected after timing out and logging in again.

Security Issues: Single Sign-Off and Application Logout

If you build custom applications using OracleAS release 9.0.4, note the following: when global logout, or single sign-off, is invoked, only the single sign-on and mod_osso cookies are cleared. This means that an OracleAS application must be coded to store single sign-on user and realm names in either the OC4J session or in the application session. The application must then compare these values to those passed by mod_osso. If a match occurs, the application must show personalized content. If no match occurs, which means that the mod_osso cookie is absent, the application must clear the application session and force the user to log in.

This section covers the following topics:

Application Login: Code Examples

The first two code examples in this section do not incorporate the logic prescribed in the section immediately preceding. The third example does incorporate this logic. Although these are Java examples, they could be examples written in other languages such as Perl, PL/SQL, and CGI.

Bad Code Example #1

// Get user name from application session. This session was
// established by the application cookie or OC4J session cookie
String username = request.getSession().getAttribute('USER_NAME');

// Get subscriber name from application session. This session was
// established by the application cookie or OC4J session cookie.
String subscriber = request.getSession().getAttribute('SUBSCRIBER_NAME');

// Get user security information from application session. This session was 
established  by the application cookie or OC4J session cookie
String user_sec_info = request.getSession().getAttribute('USER_APP_SEC');

if((username != null) && (subscriber!= null))
{
  // Show personalized user content
  show_personalized_page(username, subscriber, user_sec_info);
}
else
{
  // Send Dynamic Directive for login
  response.sendError( 499, "Oracle SSO" );

Bad Code Example #2

// Get SSO username from http header
String username = request.getRemoteUser();

// Get subscriber name from SSO http header
String subscriber = request.getHeader('OSSO-SUBSCRIBER');

// Get user security information from application session.  This session // was 
established by the application or OC4J session
String user_sec_info =request.getSession().getAttribute('USER_APP_SEC');

if((ssousername != null)&&(subscriber!= null))
{
  // Show personalized user content
show_personalized_page(username, subscriber, user_sec_info);
}
else
{
  // Send Dynamic Directive for login
response.sendError( 499, "Oracle SSO" );
}

Recommended Code

// Get user name from application session. This session was
// established by the application or OC4J session
String username = request.getSession().getAttribute('USER_NAME');

// Get subscriber name from application session. This session was
// established by the application or OC4J session
String subscriber = request.getSession().getAttribute('SUBSCRIBER_NAME');

// Get user security information from application session. This session // was 
established by the application or OC4J session
String user_sec_info = request.getSession().getAttribute('USER_APP_SEC');

// Get username and subscriber name from JAZN API */
JAZNUserAdaptor jaznuser  = (JAZNUserAdaptor)requset.getUserPrincipal();
     String ssousername   = jaznuser.getName();
     String ssosubscriber = jaznuser.getRealm().getName();

// If you are not using JAZN api then you can also get the username and
// subscriber name from mod_osso headers
String ssousername   = request.getRemoteUser();
String ssosubscriber = request.getHeader('OSSO-SUBSCRIBER');

// Check for application session. Create it if necessary.
if((username == null) || (subscriber == null) )
  {
    ...Code to create application session. Get the user information from 
    JAZN api(or mod_osso headers if you are not using JAZN api) and     populate 
the application session with user, subscriber and user     security info...
  }

if((username != null)&&(subscriber != null)
  &&(ssousername != null)&&(ssosubscriber != null)
  &&(username.equalsIgnoreCase(ssousername) == 0 )
  &&(subscriber.equalsIgnoreCase(ssosubscriber) == 0))
{
  // Show personalized user content
show_personalized_page(username, subscriber, user_sec_info);
}
else
{
     ...Code to Wipe-out application session, followed by...

// Send Dynamic Directive for login
// If you are using JAZN then you should use following code
// response.sendError( 401);

// If you are not using JAZN api then you should use following code
// response.sendError( 499, "Oracle SSO" );
}

Application Logout: Recommended Code

Most applications that authenticate users have a logout link. In a single-sign-on-enabled application, the user invokes the dynamic directive for logout in addition to other code in the logout handler of the application. Invoking the logout directive initiates single sign-off, or global logout. The example that follows shows what single sign-off code should look like in Java.

// Clear application session, if any
String l_return_url := return url to your application e.g. home page
response.setHeader( "Osso-Return-Url", l_return_url);
response.sendError( 470, "Oracle SSO" );

Go to previous page Go to next page
Oracle
Copyright © 1996, 2003 Oracle Corporation.

All Rights Reserved.
Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index