CoSigning Web Applications

Web Applications can be integrated with CoSign with minimal development effort. The general idea is that CoSign sets some environmental variables, such as $REMOTE_USER, that the web app can use. In a single-sign-on system like CoSign, the meaning of "logout" can get confusing.

General Information

The CoSign filter functions similarly to the mod_authmodule for Apache in that requests are intercepted and verified before reaching the web application protected by CoSign.

When a user makes a request to a CoSign-protected web application, the CoSign filter checks that appropriate HTTP headers containing cryptographic information have been sent by the user. If that information is missing, the filter redirects the user to the global login page at https://weblogin.pennkey.upenn.edu/login. After successful authentication the user is redirected back to the original web application, passing along the expected HTTP headers and cryptographic information which is used by the CoSign filter to verify that the user has authenticated successfully.

From the CoSign-protected web application's perspective, a user should never arrive without having a number of CGI environment variables accompanying their request. These variables contain information on the authentication method used, the username, the CoSign service to which access has been granted, and the authentication factors met by the user.

These variables and their contents are listed below:

Variable

Use

Auth_Type

Authentication method used

COSIGN_FACTOR="UPENN.EDU"

Space-separated list of the authentication factors submitted by user

COSIGN_SERVICE="cosign-domain-app-0"

Name of CoSign service as understood by filter

REMOTE_USER="darianp"

PennKey (username) of the user

A cookie named for the value of COSIGN_SERVICE is also set, containing cryptographic information used by the CoSign filter to verify the user's permission to access the service noted in COSIGN_SERVICE.

ISC recommends that CoSign-protected web applications verify the existence of the previous environment variables and cookie in addition to adhering to the following best practices.

Best Practices

General

Use SSL for access to application

SSL is not explicitly required in order to use CoSign, however ISC is requiring the use of SSL by any application that uses the University of Pennsylvania CoSign deployment for authentication.

Many of our users use public networks lacking encryption; using SSL at the application layer helps to insure integrity on a per-application basis, decreases the risk of cookie theft and information leakage, and increases the general defensive posture of the application.

Verify Authentication

The CoSign filter presents itself to web applications similarly to HTTP Basic/Digest-style authentication. Applications which tomare written to take advantage of this form of authentication (ie., consuming the REMOTE_USER environment variable) may be "CoSigned" with minimal changes.

Applications that use form-based authentication will need to be modified to skip presentation of any authentication form when the aforementioned environment has been set by the CoSign filter. Additionally, such applications also need to be modified to use the REMOTE_USER environment variable as the username/login of the authenticate user, rather than input submitted from custom authentication forms.

if ( $q->cookie( $ENV{'COSIGN_SERVICE'} ) )
{
# Authentication was successful; do something like
# redirect the user to your application homepage
# and allow them to continue on about their business
}
}
}

Verifying Authentication

<!--- get the header value struct which should contain COSIGN_FACTOR, COSIGN_SERVICE, REMOTE_REALM, and REMOTE_USER --->
<cfset headerStruct = GetHttpRequestData().headers />
<!--- make sure that the headerStruct has all the keys, they all have a value,
and that all but the remote user match the cosignStruct --->
<cfif structkeyexists(headerStruct,"COSIGN_FACTOR") and
structkeyexists(headerStruct,"COSIGN_SERVICE") and
structkeyexists(headerStruct,"REMOTE_REALM") and
structkeyexists(headerStruct,"REMOTE_USER") and
len(headerStruct.COSIGN_FACTOR) and
len(headerStruct.COSIGN_SERVICE) and
len(headerStruct.REMOTE_REALM) and
len(headerStruct.REMOTE_USER) and
comparenocase(application.cosignStruct.COSIGN_FACTOR, headerStruct.COSIGN_FACTOR) eq 0 and
comparenocase(application.cosignStruct.COSIGN_SERVICE, headerStruct.COSIGN_SERVICE) eq 0 and
comparenocase(application.cosignStruct.REMOTE_REALM, headerStruct.REMOTE_REALM) eq 0
>
<!--- check if a cookie exists that matches the cosignStruct.cosign_service,
and if so perform the login using the REMOTE_USER value --->
<cfif structkeyexists(cookie,headerStruct.COSIGN_SERVICE) and len(cookie['#headerStruct.COSIGN_SERVICE#'])>
<!--- ToDo: Authentication Successful, Perform addition Authorization if necessary,
and log user into application --->

$lang['LOGIN_ERROR_EXTERNAL_AUTH_COSIGN'] = 'You have not been authenticated by Cosign';
$lang['COSIGN_SETUP_BEFORE_USE'] = 'You have to setup CoSign authentication before you switch phpBB to this authentication method. Keep in mind that the username you use for CoSign authentication has to be the same as your phpBB username.';

// The above language defs would normally be set in the following files:
// language/en_us/common.php
// language/en_us/acp/board.php

/**
* Checks whether the user is identified to cosign
* Only allow changing authentication to cosign if the user is identified
* Called in acp_board while setting authentication plugins
*
* @return boolean|string false if the user is identified and else an error message
*/
function init_cosign()
{
global $user;

/**
* The session validation function checks whether the user is still logged in
*
* @return boolean true if the given user is authenticated or false if the session should be closed
*/
function validate_session_cosign(&$user)
{
if (!isset($_SERVER['REMOTE_USER']))
{
return false;
}