tag / iu-cas
Authentication class for CAS at IU.
Requires
- php: >=7.1.0
Requires (Dev)
- phpstan/phpstan: >=0.11.1
- phpunit/php-code-coverage: *
- phpunit/phpunit: ^7
- squizlabs/php_codesniffer: 3.*
This package is auto-updated.
Last update: 2024-12-26 07:14:34 UTC
README
IuCasAuthentication
A CAS authentication object that works with CAS @ IU. Using CAS at IU isn't complicated, and UITS even provides some sample code for PHP. This helper class aims to make the process even easier.
Note that this library does not provide any authorization (permissions based on user name), only authentication (verifying a user's credentials).
Follows PSR-4 and PSR-2 standards. Requires PHP >= 7.1. Tested against PHP v7.1 – v7.3
Installation
The preferred method of installation is with Composer.
Install with Composer
Add the following to your composer.json
file:
"tag/iu-cas": ">=1.0"
Or, install the Composer package:
composer require tag/iu-cas
Install without Composer
Download the IuCasAuthentication
class, and include or require it on your page(s).
Using IuCasAuthentication
-
Create a new authentication object. All arguments to the constructor are optional.
- The first is the URL if your application that CAS should redirect to after log in. Must be the same during authentication and validation steps. Defaults to the current URL.
- An optional second argument must be one of the CAS application codes at IU. Defaults to
'IU'
. - An optional third argument is a reference to a PSR-3 logger (such as Monolog). Used to log remote errors, if available. Defaults to `null``.
-
Call
#authenticate()
. Optional arguments are avaialable to override default behavior.
Because CAS expects applications to only authenticate once per session, the IuCasAuthentication
class stores a
successful authentication in $_SESSION
, so it is safe to use on every page (or as Middleware) to test authentication.
If the username is in $_SESSION
, #authenticate()
considers the user successfully authenticated, and does not attempt to check against CAS.
Simplest method
Let the IuCasAuthentication
helper do all of the work for you. Requires $_SESSION
to currently be writable.
This code would need to be called on every page you wish protected.
<?php // File: any.php $casHelper = new \IuCas\IuCasAuthentication(); $casHelper->authenticate(); // Default behavior is 401 (Unauthorized) and die on failure. // Pass a callback if other behavior is desired; see documentation for other options // Continue processing file as normal // After authentication, user name is available $userName = $casHelper->getUserName(); // Actually stored in $_SESSION
Recommended method
Rather than relying on the built-in behavior, pass explicit callback functions for authentication failure or success.
The two callbacks are:
- On Failure: Defaults to setting a
"401 Unauthorized"
header andexit;
. - On Success: Defaults to putting the user name returned from CAS in
$_SESSION
and returning.
$casHelper = new \IuCas\IuCasAuthentication(); $casHelper->authenticate( function () { http_response_code(401); // Unauthorized header('Location: /public'); // Failure, go to page that doesn't require authentication exit; }, function ($username) { // Success, store the user $casHelper->setUserName($success); // Sets to $_SESSION['CAS_USER']; key may be overridden via environment } );
Manage login and validation manually
Although the #authenticate()
function does all of the work for you, it's possible to manage the authentication process manually if you wish.
$casHelper = new \IuCas\IuCasAuthentication(); if (!$casHelper->getUserName()) { if (!$casHelper->getCasTicket()) { header('Location: ' . $casHelper->getCasLoginUrl(), true, 303); exit; } else { $result = $casHelper->validate(); if ($result) { // Success, logged in $_SESSION['username'] = $result; // Unless environment variables are set, this value will not be seen by IuCasAuthentication } else { // Failure header("HTTP/1.1 401 Unauthorized"); // Add optional redirect here exit; } } } // Continue processing file as normal
Example with login and validation on different pages in your app
You might use this example code to only implement CAS authentication at a specific URL. Instead of calling #authenticate()
, you might do the following:
<?php // File: login.php $appUrl = 'http://localhost/login-validate'; // URL CAS should redirect to with the CAS ticket after login $casHelper = new \IuCas\IuCasAuthentication($appUrl); header('Location: ' . $casHelper->getCasLoginUrl(), true, 303); exit;
<?php // File: login-validate.php // Remember, your application URL in validation must match the one passed in the authentication step $appUrl = 'http://localhost/login-validate'; $casHelper = new \IuCas\IuCasAuthentication($appUrl); $result = $casHelper->validate(); if ($result) { // Success, logged in $_SESSION['username'] = $result; header('Location: /', true, 303); } else { // Failure; Redirect to logout to clear session header('Location: /logout', true, 303); } exit;
Slim Framework example
The following code would work with the Slim Framework. This example also uses a PSR-3 logger and anonymous callback functions. The login functionality would be better implemented as Middleware, but this example highlights some features of the IuCasAuthentication
helper.
$app->get('/login', function (Request $request, Response $response) { $appUrl = 'https://localhost/login-validate'; $casHelper = new \IuCas\IuCasAuthentication($appUrl); return $response->withRedirect($casHelper->getCasLoginUrl(), 303); }); $app->get('/login-validate', function (Request $request, Response $response) { $appUrl = 'https://localhost/login-validate'; // URL CAS has redirected to with the CAS ticket after login // Must match the one passed to CAS in the authentication step $casHelper = new \IuCas\IuCasAuthentication($appUrl); $casHelper->setLogger($this->get('logger')); return $casHelper->authenticate( function () use (&$response) { return $response->withRedirect('/logout', 401); // Failure, go to page that doesn't require authentication }, function ($username) use (&$response) { // Do other session-setting stuff here, if desired return $response->withRedirect('/home', 303); // Success, logged in } ); });
Logging
You may pass an optional PSR-3 logger as the third parameter of the constructor. If the validation step fails, details are sent to the logger, if available.
Environment variables
In most cases, it is not necessary to create environment variables to modify the default behavior of this library for use with CAS at IU. Everything should already work without additional configuration. However, if you wish to change the default behavior, several environment variables are available.
Best practice in PHP is to put important configuration options in environment variables, perhaps in your virtual host configuration (e.g., httpd.conf
or .htacess
) or in a .env
file. Several libraries are available via Composer to assit in loading .env
files.
The three necessary URLs (login, validation, logout) as described by https://kb.iu.edu/d/atfc are included by default but may be overridden through the use of the following environment variables.
CAS_LOGIN_URL
defaults to'https://cas.iu.edu/cas/login'
CAS_VALIDATION_URL
defaults to'https://cas.iu.edu/cas/validate'
CAS_LOGOUT_URL
defaults to'https://cas.iu.edu/cas/logout'
Two additional environment variables are used:
CAS_SESSION_VAR
defaults to'CAS_USER'
, therefore the user name of the active user is available at$_SESSION[getenv('CAS_SESSION_VAR')]
. Current value is returned by#getSessionVar()
. The session variable is used by#getUserName()
and#setUserName()
, which in turn are used by#logout()
and the default success handler for#authenticate()
to store the user name response from CAS in$_SESSION
.CAS_TIMEOUT
Sets the timeout of service requests to CAS validation and logout services. Defaults to5
.
If storing authentication status somewhere other than the session variable, it's probably best to use the callback variation of #authenticate()
.
Each of these environment variable defaults is also available as a class constant. e.g., IuCasAuthentication::CAS_VALIDATION_URL
. (Exception: Timeout constant is named IuCasAuthentication::CAS_DEFAULT_TIMEOUT
.)
Release history
- v1.0
- Stable
- PHP 7.1 minimum requirement
- Simplified code, callbacks now the only way to interact with
#authenticate()
, this is a compatibility break with v0.3 - Code checked against PSR-2 with PHP_CodeSniffer
- Static analysis with phpstan at maximum level
- v0.3
- Stable
- Last full release that supports PHP 5.6+