mod_osso is an authentication module on the Oracle HTTP Server to enable applications for Single Sign On.
After successfully authenticating the user, the module transmits simple header values that applications need to validate them. Some of the useful attribute values that mod_osso passes are Osso-User-Guid (SSO user's globally unique user ID), Osso-Subscriber-Guid (Realm GUID), etc
How to protect applications using mod_osso?
mod_osso redirects the user to the SSO server only if the URL is a protected one.You can secure the URL in one of two ways: statically or dynamically.
Static directives simply protect the application while the dynamic directive also enable it to regulate user access.
I.Protecting URLs statically
You can statically protect URLs with mod_osso by applying directives to the $ORACLE_HOME/Apache/Apache/conf/mod_osso.conf
In the example that follows, a directory named /private is protected by this directive.
<IfModule mod_osso.c>
<Location /private>
AuthType Basic
require valid-user
</Location> </IfModule>
After making the entry, restart the Oracle HTTP Server: $ORACLE_HOME/opmn/bin/opmnctl restartproc ias-component=HTTP_Server
II.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 SSO System. Upon receiving a directive as part of a simple HTTP response from the application, mod_osso creates the appropriate SSO protocol message and communicates it to the SSO server.
Oracle AS supports dynamic directives for java servlets and JSPs.
The below list points out some of the commonly requested dynamic directives
Response Status/Code & Directive
401,499 --> Request Authentication
470 --> Single Sign Off
401,499 --> Request Authentication
470 --> Single Sign Off
#1: Simple Authentication
This servlet uses the request.getRemoteUser() method to check the mod_osso cookie for the user name. If the user name is absent, the servlet issues dynamic directive 499, a request for simple authentication. The key lines are in boldface.
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* Example servlet showing how to use
* Dynamic Directive for login
*/
public class SSODynLogin extends HttpServlet
{
public void service(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
String l_user = null;
// Try to get the authenticate user name
try
{
l_user = request.getRemoteUser();
}
catch(Exception e)
{
l_user = null;
}
// If user is not authenticated then generate
// dynamic directive for authentication
if((l_user == null) || (l_user.length() <= 0) )
{
response.sendError(499, "Oracle SSO");
}
else
{
// Show authenticated user information
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("
out.println("
}
}
Example #2: Single Sign-Off
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* Example servlet showing how to use
* Dynamic Directive for logout
*/
public class SSODynLogout extends HttpServlet
{
public void service (HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// Set the return URL
response.setHeader("Osso-Return-Url",
"http://my.oracle.com" );
// Send Dynamic Directive for logout
response.sendError(470, "Oracle SSO");
}
}
Global Inactivity Timeout and Dynamic Directives
If you are using Global Inactivity Timeout and Dynamic Directive for enabling Single
Sign-On for your applications, then you can use the Osso-Idle-Timeout-Exceeded HTTP
header in your application to determine the timeout status. This header value is set to true
if timeout has occurred, otherwise it is set to false.
The following example shows how you can use the Osso-Idle-Timeout-Exceeded HTTP
header:
String timeoutStatus = request.getHeader("Osso-Idle-Timeout-Exceeded")
// Check if user has timedout
if ( (timeoutStatus != null) && timeoutStatus.equalsIgnoreCase("true") )
{
response.setHeader( "Osso-Paranoid", "true" );
response.sendError(499, "Oracle SSO");
}
else
{
// Display page content here
}
Best Practices: Code Examples
// 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" );
}
This servlet uses the request.getRemoteUser() method to check the mod_osso cookie for the user name. If the user name is absent, the servlet issues dynamic directive 499, a request for simple authentication. The key lines are in boldface.
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* Example servlet showing how to use
* Dynamic Directive for login
*/
public class SSODynLogin extends HttpServlet
{
public void service(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
String l_user = null;
// Try to get the authenticate user name
try
{
l_user = request.getRemoteUser();
}
catch(Exception e)
{
l_user = null;
}
// If user is not authenticated then generate
// dynamic directive for authentication
if((l_user == null) || (l_user.length() <= 0) )
{
response.sendError(499, "Oracle SSO");
}
else
{
// Show authenticated user information
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("
Welcome to Oracle Single Sign-On
");out.println("
");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("");
}
}
Example #2: Single Sign-Off
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* Example servlet showing how to use
* Dynamic Directive for logout
*/
public class SSODynLogout extends HttpServlet
{
public void service (HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// Set the return URL
response.setHeader("Osso-Return-Url",
"http://my.oracle.com" );
// Send Dynamic Directive for logout
response.sendError(470, "Oracle SSO");
}
}
Global Inactivity Timeout and Dynamic Directives
If you are using Global Inactivity Timeout and Dynamic Directive for enabling Single
Sign-On for your applications, then you can use the Osso-Idle-Timeout-Exceeded HTTP
header in your application to determine the timeout status. This header value is set to true
if timeout has occurred, otherwise it is set to false.
The following example shows how you can use the Osso-Idle-Timeout-Exceeded HTTP
header:
String timeoutStatus = request.getHeader("Osso-Idle-Timeout-Exceeded")
// Check if user has timedout
if ( (timeoutStatus != null) && timeoutStatus.equalsIgnoreCase("true") )
{
response.setHeader( "Osso-Paranoid", "true" );
response.sendError(499, "Oracle SSO");
}
else
{
// Display page content here
}
Best Practices: Code Examples
// 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" );
}
hey, question for you. i have something like this working correctly. however, i need to make a server-to-server call behind the scenes to this server from a Java application to collect some data. i know the user has already authenticated to SSO if they can reach that page. do you know of any way to configure the Location block to exempt a specific IP from the SSO requirement...? i.e., all requests require SSO unless that request is coming from 172.16.xx.xxx?
ReplyDelete