Oracle + PHP
Single Sign-On for PHP Pages
By David Jason Bennett
Secure your PHP pages using Oracle Application Server 10g Single Sign-On
If you've configured PHP to run under Oracle Application Server and want to bring your PHP pages under the umbrella of a single identity management infrastructure, then you will want to pay particular attention to this article. It focuses on two simple methods for SSO- (Single Sign-On) enabling PHP pages, both of which take advantage of an Oracle Application Server Enterprise Edition feature called mod_osso (see sidebar), an Apache module that integrates with the SSO server to authenticate users.
Note that mod_osso must be configured with Oracle HTTP Server on the same application server in which PHP is installed in order to take advantage of the methods described here. For more information about configuring mod_osso, refer to the Single Sign-On Application Developers Guide.
PHP and Oracle Application Server
PHP is a powerful, flexible open source scripting language typically used to generate dynamic content in web pages. (PHP is similar to Perl, but much less complicated. For more background, visit OTN's Open Source Developer Center.) Out of the box, PHP provides a rich set of features and services including LDAP, IMAP, SNMP, NNTP, POP3, HTTP, XML, XSL, and database access modules for most database products including Oracle. PHP can run as a CGI under Apache or be configured as an Apache Web Server module.
Integrating PHP with Oracle Application Server is very easy because Oracle HTTP Server is an Apache Web Server. Mod_osso is integrated with Oracle Application Server as an Apache module, so it is a simple matter to take advantage of the app server's features to protect PHP pages.
Method 1: The PHP Proxy Page Method
Mod_osso protects web pages through registered URL patterns. It examines all requests that pass through the Oracle HTTP Server; if a request or URL contains a protected pattern, and the requestor has not already authenticated to the SSO server, the requestor is redirected to the SSO login screen. The Proxy Page method of SSO-enabling a PHP page takes advantage a registered URL pattern that is mapped to a specific PHP page. The URL is registered with mod_osso by recording the pattern in the mod_osso.conf file as illustrated here:
<Location /php_apps/ssoreroute.php>
require valid-user
authType Basic
</Location>
The protected PHP page acts as a proxy for all other PHP pages that you want to protect.
In Figure 1, a PHP file (SSOUtils.php; see Listing 1) acts as a library and contains a user-defined PHP function called checkAuthenticated() and is included in the PHP page (MyPage.php; see Listing 2) we are trying to SSO enable. The function is executed at the top of the page we are SSO enabling and checks to see if the requestor has already authenticated to the SSO server. If the requestor has not authenticated, the requestor is automatically redirected to the php proxy page, whose URL pattern is registered with mod_osso. The php proxy page (ssoreroute.php) takes the URL of the calling page as a parameter. The requestor is redirected to the login screen by mod_osso. After successful authentication, the requestor is redirected back to the PHP proxy page, which in turn redirects the requestor back to the calling page.
The PHP script for the function, checkAuthenticated(), is very straightforward:
function checkAuthenticated(){
$SSO_REROUTE = "/php_apps/ssoreroute.php?p_redirect_url=";
$SSO_USER = getenv("REMOTE_USER");
if (empty($SSO_USER)){
header("Location: ".$SSO_REROUTE.$_SERVER['PHP_SELF']);
}
}
The script for the PHP proxy page is equally straightforward:
<?php
//Redirect back to requested page.
header("Location:".$_REQUEST['p_redirect_url']);
?>
But login is only part of the SSO server's full functionality. We also have the ability to logout, commonly known as Single Sign-Off. Logging out of an SSO-enabled page is simply a matter of redirecting to the URL /osso_logout?p_done_url=<return url>. The logout URL is a feature the SSO server.
The following function, ssoLogoutLink(<return url>), creates a custom logout link:
function ssoLogoutLink($RETURN_URL=""){
$DONE_URL = "";
if (empty($RETURN_URL)){
$DONE_URL=$_SERVER['PHP_SELF'];
}else{
$DONE_URL=$RETURN_URL;
}
$SSO_LOGOUT_URL = "/osso_logout?p_done_url=".$DONE_URL;
$LOGOUT_LINK = "<a href=\"".$SSO_LOGOUT_URL."\">Click here to Logout</a>";
return $LOGOUT_LINK;
}
The proxy page method is a very simple way to protect PHP pages leveraging basic mod_osso functionality. However, it does lock the requestor into the default logout and return URLs associated with mod_osso. Consequently, this method does not provide much granular control. In contrast, the method discussed in the next section provides more granular control through the use of servlets and dynamic directives.
Method #2: SSO LoginProxy and LogoutProxy Servlet Method
Dynamic Directives are feature of mod_osso that allow the developer some granular control over how an application interacts with the SSO server. Dynamic directives consist of HTTP response headers coupled with a set special error codes. Applications that use dynamic directives for initiating authentication and logout are not required to register a URL pattern with mod_osso. The one caveat is that dynamic directives must be used in conjunction with an OC4J (J2EE) application such as a servlet or a JSP.
SSO enabling a PHP page that takes advantage of dynamic directives can be achieved through the use of a proxy servlet that issues dynamic directives to mod_osso on behalf of the requesting PHP page. The method described here (see Figure 2) uses two servlets, one for login and one for logout.
In Figure 2, a PHP file (SSOUtils.php; see Listing 1) acts as a library and contains a user-defined PHP function called checkAuthenticatedProxy() and is included in the PHP page (Listing 2) we are trying to SSO enable. The function is executed at the top of the page we are SSO enabling and checks to see if the requestor has already authenticated to the SSO server. If the requestor has not authenticated, the requestor is automatically redirected to the login proxy servlet along with a parameter specifying the return URL to the calling page. The login proxy servlet issues the required dynamic directive to initiate a SSO login request to the SSO server. The requestor is redirected to the login screen by mod_osso. After successful authentication, the requestor is redirected back to the return URL received by the login proxy servlet from the calling page.
The process for logging out is similar: a PHP function, ssoLogoutLinkProxy(<return url>), is executed to create a hyperlink to the logout proxy servlet. The logout proxy servlet issues the required dynamic directive to initiate a SSO logout request to the SSO server. The requestor is logged out and redirected to the SSO logout screen. After clicking the Return button in the logout screen, the requestor is redirected back to the return URL received by the logout proxy servlet from the calling page.
The PHP script for the function, checkAuthenticatedProxy(), is basically the same as for checkAuthenticate(), described in the previous method. The primary difference in the functions is the redirection URL. The PHP script for checkAuthenticatedProxy() is:
function checkAuthenticatedProxy(){
$SSO_REROUTE = "/ssoproxy/loginProxy?p_redirect_url=";
$SSO_USER = getenv("REMOTE_USER");
if (empty($SSO_USER)){
header("Location: ".$SSO_REROUTE.$_SERVER['PHP_SELF']);
}
}
Again, the PHP script for the function ssoLogoutLinkProxy(<return url>) is basically the same as for the function ssoLogutLink(<return url; the primary difference in the functions is the redirection URL. The PHP script for ssoLogoutLinkProxy(<return url>) is:
function ssoLogoutLinkProxy($RETURN_URL=""){
$DONE_URL = "";
if (empty($RETURN_URL)){
$DONE_URL=$_SERVER['PHP_SELF'];
}else{
$DONE_URL=$RETURN_URL;
}
$SSO_LOGOUT_URL = "/ssoproxy/logoutProxy?p_done_url=".$DONE_URL;
$LOGOUT_LINK = "<a href=\"".$SSO_LOGOUT_URL."\">Click here to Logout</a>";
return $LOGOUT_LINK;
}
The Java classes in see Listing 3 illustrate the code required to create each of the proxy servlets used in the method described above. Both servlets contain a reference to a Java class called SSOUtilities. SSOUtilities is a class that contains canned methods for issuing dynamic directives and other SSO related functions. Both servlets are mapped to specific URL patterns as defined in the web.xml file associated with the application. Next Steps
Download PHP software and documentation.
Read "Getting started with Oracle and PHP," by Sean Hull
Read "Fast Track To Single Sign-On," by David Jason Bennett
Visit and bookmark the Open Source Developer Technology Center
Download Oracle Application Server
Download Oracle Application Server Security Documentation
As you can see, the Login Proxy and Logout Proxy Servlet Method provides more granular control with respect to how the PHP application flows after logging in and after logging out.
Which Method Should I Choose?
After reviewing both methods for SSO enabling your PHP pages, you may want to ask the logical questions "Which method should I choose?", or even better, "Why would I choose the more complex solution over the simpler one ?" The answer to those questions depends upon how much control you require with respect to SSO. If all your application or page requires is basic protection, then the PHP Proxy Method will meet your needs. But if your application requires the more granular control provided through the use of dynamic directives, then the SSO LoginProxy and LogoutProxy Method would be the better choice.
The first method works well, but does not provide a great amount of flexibility; it also requires that a URL pattern be physically registered with mod_osso, whereas the second method does not. The second solution not only provides the flexibility of dynamic directives, but can extended or altered to meet a more customized set of requirements.
Good for the Gander
In theory, any scripting language (Perl, Python, ColdFusion) that can be deployed under Oracle Application Server could use the same methods I've described to interact with mod_osso and become SSO enabled.
Jason Bennett ( David.Bennett@oracle.com) is a technical manager with Oracle Government, Education, and Health Consulting specializing in Internet technologies.
A Short Look at Mod_osso
Mod_osso is an Apache module that acts as the single point of contact with SSO server. In the past, SSO-enabling an application required that the application be registered with the SSO server as a partner application. Mod_osso is registered as a partner application (meaning that it delegates authentication to the SSO server) and acts as an authentication proxy for other applications.
The mechanics of mod_osso are very straightforward. When a user request comes to the web server from a user, mod_osso looks for its own encrypted session cookie. If the mod_osso cookie is found, the user has been authenticated and the request is served. If the mod_osso cookie is not found, the user is redirected to the SSO server and asked to authenticate. If the login is successful, then a mod_osso cookie is set in the users browser. When the mod_osso cookie is set, the user can access any other SSO application without having to re-authenticate. Keep in mind, however, that authentication is only good for a single browser session. |