Oracle Single Sign-On Application Developer's Guide Release 3.0.6 Part Number A86782-03 |
|
This chapter provides some sample programs and examples of code to illustrate for developers how to implement partner applications.
This chapter contains the following topics:
Writing a partner application using PL/SQL requires Oracle Web Agent packages for web related functionality and requires that two procedures be implemented. In the following code example, these two public procedures perform all redirection and parsing functionality. The public procedures are as follows:
This procedure constructs the application URL and it requires authentication to access it. This procedure checks to see if the application cookie exists and user information can be retrieved. Otherwise it redirects the user to the SSO server by generating redirect url.
This procedure gets the URLC token from the SSO server, decrypts it, and retrieves user information and the requested url. It sets the application cookie and redirects the browser to the partner application URL ( i.e. SSOAPP URL).
CREATE OR REPLACE PACKAGE sample_sso_papp IS PROCEDURE ssoapp; PROCEDURE sign_on ( urlc IN VARCHAR2 ) END sample_sso_papp; / show errors package sample_sso_papp CREATE OR REPLACE PACKAGE BODY sample_sso_papp IS l_listener_token VARCHAR2(1000) := 'app1:ssosvr:443'; l_requested_url VARCHAR2(1000) := 'http://www.ssopapp.com/pls/ssodad/schamaname/sample_sso_papp.sso_papp'; l_cancel_url VARCHAR2(1000) := 'http://www.ssopapp.com'; l_cookie_name VARCHAR2(1000) := 'SSO_SQLPAPP_ID'; l_cookie_path VARCHAR2(1000) := '/'; l_cookie_domain VARCHAR2(1000) := 'www.ssopapp.com'; FUNCTION get_user_info RETURN VARCHAR2 IS l_user_info VARCHAR2(1000); l_app_cookie owa_cookie.cookie; BEGIN l_app_cookie := owa_cookie.get(l_cookie_name); l_user_info := l_app_cookie.vals(1); return l_user_info; END get_user_info; PROCEDURE ssoapp IS l_user_info VARCHAR2(1000); l_gen_redirect_url VARCHAR2(32000); BEGIN l_user_info := get_user_info; IF l_user_info IS NULL THEN l_gen_redirect_url := wwsec_sso_enabler_private.generate_redirect ( p_lsnr_token => l_listener_token, urlrequested => l_requested_url, urloncancel => l_cancel_url ); owa_util.redirect_url(l_gen_redirect_url); ELSE begin htp.init; exception when others then null; end; htp.htmlOpen; htp.headOpen; htp.print('<meta http-equiv="Content-Type"' || ' content="text/html; charset=iso-8859-1">'); htp.title('PL/SQL based SSO Partner Application'); htp.headCLose; htp.bodyOpen; htp.print('User Information:' || l_user_info || '<br>'); htp.bodyClose; htp.htmlClose; END IF; EXCEPTION WHEN OTHERS THEN RAISE; END ssoapp; PROCEDURE sign_on ( urlc IN VARCHAR2 ) IS l_urlc VARCHAR2(32000); l_sso_user_name VARCHAR2(1000); l_ip_address VARCHAR2(1000); l_sso_time_remaining VARCHAR2(1000); l_site_time_stamp VARCHAR2(1000); l_url_requested VARCHAR2(1000); l_unused_param VARCHAR2(1000); BEGIN -- Process URLC token wwsec_sso_enabler_private.parse_url_cookie ( p_lsnr_token => l_listener_token, encrypted_urlcookie => urlc, ssousername => l_sso_user_name, ipadd => l_ip_address, ssotimeremaining => l_sso_time_remaining, sitetimestamp => l_site_time_stamp, urlrequested => l_url_requested, newsitekey => l_unused_param ); -- Set application cookie begin htp.init; exception when others then null; end; owa_util.mime_header('text/html', FALSE); owa_cookie.send ( name => l_cookie_name, value => l_sso_user_name, expires => null, path => l_cookie_path, domain => l_cookie_domain ); -- Redirect user to the requested application url htp.htmlOpen; htp.headOpen; htp.meta(chttp_equiv=>'Refresh', cname=> 'Requested URL', ccontent=>'0 URL=' || l_url_requested); htp.headClose; htp.htmlClose; EXCEPTION WHEN OTHERS THEN RAISE; END sign_on; END sample_sso_papp; / show errors package body sample_sso_papp
Initially, the partner application redirects the user to the Login Server for authentication and, after successful authentication, sets its own application session cookie. Any future request first attempts to validate the application session cookie. If the application session cookie is not found, then the partner application redirects the user to the Login Server. To avoid contacting Login Server for authentication verification of every user request, all partner applications should maintain their own application session.
This section contains the following topics
To implement the partner application in Java, we will implement a generic bean which will be used in Servlet as well as JSP based applications.
// SSOEnablerBean.java import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Cookie; import java.net.URL; import java.net.InetAddress; import java.sql.DriverManager; import java.sql.Connection; import oracle.security.sso.enabler.SSOEnabler; import oracle.security.sso.enabler.SSOUserInfo; import oracle.security.sso.enabler.SSOEnablerUtil; import oracle.security.sso.enabler.SSOEnablerException; public class SSOEnablerBean { private String m_listenerToken = null; private String m_requestedUrl = null; private String m_onCancelUrl = null; private String m_pappCookieName = null; private String m_pappCookieDomain = null; private String m_pappCookieScope = null; private String m_pappCookieDesc = null; private String m_dbCred = null; private String m_dbhost = null; private String m_dbport = null; private String m_dbsid = null; /** * Default constructor */ public SSOEnablerBean() { } /** * Set listener token */ public void setListenerToken(String p_listenerToken) { m_listenerToken = p_listenerToken; } /** * Set requested and cancel url */ public void setUrls(String p_requestedUrl, String p_cancelUrl) { m_requestedUrl = p_requestedUrl; m_onCancelUrl = p_cancelUrl; } /** * Set application cookie information */ public void setAppCookieInfo(String p_name, String p_domain, String p_path) { m_pappCookieName = p_name; m_pappCookieDomain = p_domain; m_pappCookieScope = p_path; m_pappCookieDesc = "SSO application cookie"; } public void setDbConnectionInfo(String p_schema , String p_password, String p_hostname, String p_port, String p_sid) { m_dbCred = p_schema + "/"+ p_password; m_dbhost = p_hostname; m_dbport = p_port; m_dbsid = p_sid; } /** * This method will return SSO user information. If the user is not * authenticated against SSO server then it will redirect user to the SSO * Server for authentication */ public String getSSOUserInfo(HttpServletRequest p_request, HttpServletResponse p_response) throws SSOEnablerException { String l_userName = null; if(p_response == null || p_response == null) { throw new SSOEnablerException("Http objects are null"); } if(m_listenerToken == null) { throw new SSOEnablerException("Listener token is null"); } if(m_requestedUrl == null || m_onCancelUrl == null) { throw new SSOEnablerException( "Requested URL and cancel URL must be set"); } try { // Get database connection Connection l_db_con = getDbConnection(); // Try to get user information from application cookie l_userName = getUserInfo(p_request); if(l_userName == null) { // Create SSOEnabler object SSOEnabler l_ssoEnabler = new SSOEnabler(l_db_con); // Create redirect URL to the SSO server for user authentication String l_redirectUrl = l_ssoEnabler.generateRedirect(m_listenerToken, m_requestedUrl, m_onCancelUrl); // close database connection closeDbConnection(l_db_con); // p_response.sendRedirect(l_redirectUrl); // Since the redirect URL is usually large so send the // redirect URL input parameters using HTTP post method instead // of usual GET method of // HttpServletResponse.sendRedirect String htmlPostForm = SSOEnablerUtil.genHtmlPostForm(l_redirectUrl); p_response.getWriter().println(htmlPostForm); return null; } else { // We got this user information from application cookie SSOEnablerUtil l_ssoAppUtil = new SSOEnablerUtil(l_db_con); return l_ssoAppUtil.unbakeAppCookie(m_listenerToken, l_userName); } } } catch(Exception e) { throw new SSOEnablerException(e.toString()); } } /** * Get user information from application cookie */ private String getUserInfo(HttpServletRequest p_request) throws SSOEnablerException { boolean l_gotPappCookie = false; String l_userInfo = null; if(m_pappCookieName == null) throw new SSOEnablerException("Cookie name is null"); try { Cookie[] l_cookies = p_request.getCookies(); for(int i=0; i < l_cookies.length; i++) { Cookie l_pappCookie = l_cookies[i]; if (l_pappCookie.getName().equals(m_pappCookieName)) { l_gotPappCookie = true; l_userInfo = l_pappCookie.getValue(); break; } } } catch(Exception e) { return null; } if( (l_userInfo != null) && (l_userInfo.length() > 0) ) { return l_userInfo; } else { return null; } } /** * This method will set application cookie from SSO server token and * then redirect user to the application url */ public void setPartnerAppCookie(HttpServletRequest p_request, HttpServletResponse p_response) throws SSOEnablerException { if(p_response == null || p_response == null) { throw new SSOEnablerException("Http objects are null"); } if(m_listenerToken == null) { throw new SSOEnablerException("Listener token is null"); } if( m_pappCookieName == null || m_pappCookieDomain == null || m_pappCookieScope == null || m_pappCookieDesc == null) { throw new SSOEnablerException( "Application cookie information is not available"); } SSOUserInfo l_ssoUserInfo = null; try { String l_urlParam = p_request.getParameterValues("urlc")[0]; if(l_urlParam != null) { // Get database connection Connection l_db_con = getDbConnection(); // Create SSOEnabler object SSOEnabler l_ssoEnabler = new SSOEnabler(l_db_con); // Get IP address of the client InetAddress l_clientIp = InetAddress.getByName(p_request.getRemoteAddr()); l_ssoUserInfo = l_ssoEnabler.getSSOUserInfo(m_listenerToken, l_urlParam, l_clientIp); // Set application cookie SSOEnablerUtil l_ssoAppUtil = new SSOEnablerUtil(l_db_con); String l_bakedAppCookie = l_ssoAppUtil.bakeAppCookie(m_listenerToken, l_ssoUserInfo.getSSOUserName()); // Close database connection closeDbConnection(l_db_con); // Create application cookie and set it // ** IMPORTANT ** // Time stamp **must** be added in this cookie and should implement // application cookie time out based on user inactivity etc. Cookie l_appCookie = new Cookie(m_pappCookieName, l_bakedAppCookie); l_appCookie.setDomain(m_pappCookieDomain); // In-memory cookie for better security l_appCookie.setMaxAge(-1); l_appCookie.setPath(m_pappCookieScope); l_appCookie.setComment(m_pappCookieDesc); p_response.addCookie(l_appCookie); String reqRedirHtmlStr = SSOEnablerUtil.genRedirect(l_ssoUserInfo.getUrlRequested()); p_response.getWriter().println(reqRedirHtmlStr); } else { throw new SSOEnablerException( "SSO server returned null user information"); } } catch(Exception e) { throw new SSOEnablerException(e.toString()); } } /** * Remove application cookie to end user application session */ public void removePartnerAppCookie(HttpServletResponse p_response) throws SSOEnablerException { if(p_response == null) { throw new SSOEnablerException("HttpServletResponse is null"); } if( m_pappCookieName == null || m_pappCookieDomain == null || m_pappCookieScope == null { throw new SSOEnablerException( "Application cookie information is not available"); } Cookie l_AppCookie = new Cookie(m_pappCookieName, "End application sesion"); l_AppCookie.setDomain(m_pappCookieDomain); l_AppCookie.setMaxAge(0); l_AppCookie.setPath(m_pappCookieScope); l_AppCookie.setComment(m_pappCookieDesc); p_response.addCookie(l_AppCookie); } /** * Get database connection to the schema where partner application * packages are installed and configured * * ** IMPORTANT ** * This method **must** be implemented as pooled database connection for * better performance */ private Connection getDbConnection() throws SSOEnablerException { // Database connection string String l_connect_string = "jdbc:oracle:thin:" + m_dbCred + "@" + "(description=" + "(address_list=" + "(address=(protocol=tcp)(host=" + m_dbhost + ")(port=" + m_dbport + ")))" + "(source_route=yes)(connect_data=(sid=" + m_dbsid + ")))"; try { // Get database connection Class.forName ("oracle.jdbc.driver.OracleDriver"); Connection l_db_con = DriverManager.getConnection(l_connect_string); return l_db_con; } catch(Exception e) { throw new SSOEnablerException(e.toString()); } } /** * Release database connection to the schema where partner application * packages are installed and configured * * ** IMPORTANT ** * This method **must** be implemented as pooled release database * connection for better performance */ private void closeDbConnection(Connection p_dbConn) throws SSOEnablerException { try { p_dbConn.close(); } catch(Exception e) { throw new SSOEnablerException(e.toString()); } } }
A sample servlet based partner application could be implemented using one bean and three servlets.
SSOPartnerServlet
application URL. This servlet will get the user information with the help of SSOEnablerServletBean
. If the user information can be found, then it is used inside the application. Otherwise, the browser redirects the user to the Single Sign-On server.
SSOSignOnServlet
URL.
SSOEnablerServletBean
.
This bean is derived from the SSOEnablerBean
and implements the necessary methods for servlet based application.
This servlet is the main partner application servlet. To access this servlet, the user must authenticate to the SSO server. This servlet redirects the unauthenticated user to the SSO server.
This servlet parses the URLC token received from SSO server, sets the application cookie, and redirects the user to the requested web application URL (i.e. SSOPartnerServlet
)
This servlet removes the application session of the partner application
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import oracle.security.sso.enabler.SSOEnablerException; public class SSOEnablerServletBean { private SSOEnablerBean m_enablerBean = null; /** * Default constructor */ public SSOEnablerServletBean() { m_enablerBean = new SSOEnablerBean(); m_enablerBean.setListenerToken("servletapp2:loginserver:443"); m_enablerBean.setUrls( "http://app2.xyz.com:80/servlet/SSOPartnerServlet", "http://app2.xyz.com:80"); m_enablerBean.setAppCookieInfo("SSO_APP2_SERVLET_ID", "app2.xyz.com", "/"); m_enablerBean.setDbConnectionInfo("papp", "papp", "db-hostname", "1521", "db-sid"); } public String getSSOUserInfo(HttpServletRequest p_request, HttpServletResponse p_response) throws SSOEnablerException { return m_enablerBean.getSSOUserInfo(p_request, p_response); } public void setPartnerServletAppCookie(HttpServletRequest p_request, HttpServletResponse p_response) throws SSOEnablerException { m_enablerBean.setPartnerAppCookie(p_request, p_response); } public void removeServletAppCookie(HttpServletResponse p_response) throws SSOEnablerException { m_enablerBean.removePartnerAppCookie(p_response); } }
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServlet; import javax.servlet.ServletException; import java.io.PrintWriter; public class SSOPartnerServlet extends HttpServlet { /** * The HTTP GET request will show the application content of the user * if he/she is already authenticated, otherwise he/she will be redirected * to the Single Sign-On server */ public void doGet(HttpServletRequest p_request, HttpServletResponse p_response) throws ServletException { p_response.setContentType("text/html"); if(p_request == null || p_response == null) { throw new ServletException("Http objects are null"); } try { PrintWriter l_out = p_response.getWriter(); SSOEnablerServletBean l_ssobean = new SSOEnablerServletBean(); String l_userInfo = l_ssobean.getSSOUserInfo(p_request, p_response); if(l_userInfo != null) { // Display some application content for the SSO user l_out.println("<HTML><HEAD><TITLE> Servlet based SSO Partner" + "Application</TITLE></HEAD><BODY>"); l_out.println("<H3><center>Servlet based SSO Partner" +"Application</center></H3>"); l_out.println("<P><center>User Information: " + l_userInfo + "<center><BR>"); l_out.println("<P><center>" +"<A HREF='/servlet/SSOPartnerLogoutServlet'>" +"Logout</A><center></P>"); l_out.println("</BODY></HTML>"); } else { // Display redirection to SSO server message l_out.println("<HTML><HEAD><TITLE>"Servlet based SSO Partner" + "Application</TITLE></HEAD><BODY>"); l_out.println("<center>Please wait while redirecting to the" + "SSO server...</center>"); l_out.println("</BODY></HTML>"); } } catch(Exception e) { try { p_response.getWriter().println("Error " + e.toString()); } catch(Exception e1) { throw new ServletException(e1.toString()); } } } }
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServlet; import javax.servlet.ServletException; import java.io.PrintWriter; public class SSOSignOnServlet extends HttpServlet { /** * The HTTP Post will set application cookie from SSO server token and * then redirect user to the Servlet based partner application */ public void doPost(HttpServletRequest p_request, HttpServletResponse p_response) throws ServletException { p_response.setContentType("text/html"); if(p_request == null || p_response == null) { throw new ServletException("Http objects are null"); } try { SSOEnablerServletBean l_ssobean = new SSOEnablerServletBean(); l_ssobean.setPartnerServletAppCookie(p_request, p_response); } catch(Exception e) { try { p_response.getWriter().println("Error " + e.toString()); } catch(Exception e1) { throw new ServletException(e1.toString()); } } } }
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServlet; import javax.servlet.ServletException; import java.io.PrintWriter; public class SSOPartnerLogoutServlet extends HttpServlet { public void doGet(HttpServletRequest p_request, HttpServletResponse p_response) throws ServletException { p_response.setContentType("text/html"); if(p_request == null || p_response == null) { throw new ServletException("Http objects are null"); } try { SSOEnablerServletBean l_ssobean = new SSOEnablerServletBean(); l_ssobean.removeServletAppCookie(p_response); PrintWriter l_out = p_response.getWriter(); l_out.println("<HTML><HEAD><TITLE>" + "Servlet based SSO Partner Application</TITLE></HEAD><BODY>"); l_out.println("<center><H3>Servlet based SSO Partner" + " Application</H3><center>"); l_out.println("<P><center>You are logged off from application" + " session<center><BR>"); l_out.println("<P><center>" +"<A HREF='/servlet/SSOPartnerServlet'>Login</A><center></P>"); l_out.println("</BODY></HTML>"); } catch(Exception e) { try { p_response.getWriter().println("Error " + e.toString()); } catch(Exception e1) { throw new ServletException(e1.toString()); } } } }
The JSP based partner application can be implemented using a Java bean for generating a redirection URL and processing the redirected URL parameter from the SSO server. A JSP page should embed this bean, which can be included in all JSP based applications that require SSO functionality.
papp.js
p page.
ssoinclude.jsp
page. If the user information can be found, then it is used by the application. Otherwise, the browser redirects the user to the Single Sign-On server using SSOEnablerJspBean
.
ssosignon.jsp
page. This page sets the application cookie and redirects the user to the requested application URL using SSOEnablerJspBean
.
A sample JSP based application can be implemented by implementing the following bean and JSP pages:
This bean has the getSSOUserInfo
method which returns the user information when the application cookie is already set. Otherwise, it redirects the user to the SSO server for authentication.
This page embeds the SSOEnablerJsp
bean and should be included all application JSP pages where SSO functionality is necessary.
This page embeds the SSOEnablerJspBean
for generating redirection URL and processing the redirected URL parameter received from the SSO server.
This page is the main application page and requires SSO functionality. This page must include the ssoinclude.jsp
page to get the user information.
This JSP page removes the application session
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import oracle.security.sso.enabler.SSOEnablerException; public class SSOEnablerJspBean { private SSOEnablerBean m_enablerBean = null; /** * Default constructor */ public SSOEnablerJspBean() { m_enablerBean = new SSOEnablerBean(); m_enablerBean.setListenerToken("jspapp1:loginserver:443"); m_enablerBean.setUrls("http://app1.xyz.com:80/jsp/papp.jsp", "http://app1.xyz.com:80"); m_enablerBean.setAppCookieInfo("SSO_APP1_JSP_ID", "app1.xyz.com", "/"); m_enablerBean.setDbConnectionInfo("papp", "papp", "db-hostname", "1521", "db-sid"); } public String getSSOUserInfo(HttpServletRequest p_request, HttpServletResponse p_response) throws SSOEnablerException { return m_enablerBean.getSSOUserInfo(p_request, p_response); } public void setPartnerJspAppCookie(HttpServletRequest p_request, HttpServletResponse p_response) throws SSOEnablerException { m_enablerBean.setPartnerAppCookie(p_request, p_response); } public void removeJspAppCookie(HttpServletResponse p_response) throws SSOEnablerException { m_enablerBean.removePartnerAppCookie(p_response); } }
<%@ page language="java" import="oracle.security.sso.enabler.*" %> <jsp:useBean id="ssoObj" scope="page" class="SSOEnablerJspBean" /> <% String usrInfo = ssoObj.getSSOUserInfo(request, response); if(usrInfo == null) { %> <center> Please wait while redirecting to the Single Sign-On server... </center> <% } %>
<%@ page language="java" import="oracle.security.sso.enabler.*" %> <jsp:useBean id="ssoObj" scope="page" class="SSOEnablerJspBean" /> <% ssoObj.setPartnerJspAppCookie(request, response); %>
<%@ page buffer="5" autoFlush="true" %> <%@ include file="ssoinclude.jsp" %> <% if(usrInfo != null) { response.getWriter().println("<center><h2>" +"Sample JSP Partner Application</FONT></h2></center>"); response.getWriter().println("<center>User information :" + usrInfo +"</center>"); response.getWriter().println("<center>" + "<a href='papplogoff.jsp'>Logoff</a></center>"); } else { response.getWriter().println("<center>User information " + "not found</center>"); } %>
<%@ page language="java" import="oracle.security.sso.enabler.*" %> <jsp:useBean id="ssoObj" scope="page" class="SSOEnablerJspBean" /> <% try { ssoObj.removeJspAppCookie(response); } catch(Exception e) { %> <center> Error in ending JSP application session. Please quit your all browser windows. </center> <% return; } %> <center> You are logged off from JSP application session <br> <a href="papp.jsp">Login</a> </center>
|
Copyright © 1996-2000 Oracle Corporation. All Rights Reserved. |
|