Skip to content
Snippets Groups Projects
Commit 6be9c668 authored by Jaime Perez Crespo's avatar Jaime Perez Crespo
Browse files

Extract the papi module out to its own repository. This closes #156.

parent 88a223eb
No related branches found
No related tags found
No related merge requests found
...@@ -76,7 +76,7 @@ The next step is to configure the way users authenticate on your IdP. Various mo ...@@ -76,7 +76,7 @@ The next step is to configure the way users authenticate on your IdP. Various mo
[`authtwitter:Twitter`](./authtwitter:oauthtwitter) [`authtwitter:Twitter`](./authtwitter:oauthtwitter)
: Authenticate with your Twitter account using the Twitter OAuth API. : Authenticate with your Twitter account using the Twitter OAuth API.
[`papi:PAPI`](./papi:papi) [`papi:PAPI`](https://github.com/rediris-es/simplesamlphp-module-papi/blog/master/README.md)
: Authenticate by means of the PAPI protocol. : Authenticate by means of the PAPI protocol.
In this guide, we will use the `exampleauth:UserPass` authentication module. This module does not have any dependencies, and is therefore simple to set up. In this guide, we will use the `exampleauth:UserPass` authentication module. This module does not have any dependencies, and is therefore simple to set up.
......
PAPI module
===========
The PAPI module provides a single authentication module:
`papi:PAPI`
: Authenticate using the PAPI protocol.
This authentication module makes use of an external library, phpPoA, in order to
authenticate users by means of the PAPI protocol. It can therefore
be used to bridge between protocols, behaving like a PAPI `Point of Access` or
Service Provider.
To use this module, enable it by creating a file named `enable` in the
`modules/papi/` directory. Then you need to add an authentication source which
makes use of the `papi:PAPI` module to the `config/authsources.php` file:
'example-papi' => array(
'papi:PAPI',
/*
* The site identifier that allows the module to determine which
* configuration of the phpPoA to use.
*/
'site' => 'example',
/*
* The Home Locator Identifier. Use this if your phpPoA configuration
* points to a GPoA instead of an Authentication Server (AS), and you
* want to skip the identity provider selection page, by directly
* selecting one here.
*/
'hli' => 'exampleAS',
),
User attributes
---------------
If user attributes were received upon succesful authentication, then their exact
names and values will be transferred into the $state['Attributes'] array. Please
note that attribute name mapping could be needed. There's no support for asking
specific attributes during PAPI authentication. Attributes released to a Service
Provider must be agreed and configured on beforehand.
\ No newline at end of file
<?php
/**
* Authenticate using PAPI protocol.
*
* @author Jaime Perez, RedIRIS
* @package simpleSAMLphp
*/
include("poa2/PoA.php");
class sspmod_papi_Auth_Source_PAPI extends SimpleSAML_Auth_Source {
/**
* The string used to identify our states.
*/
const STAGE_INIT = 'sspmod_papi_Auth_Source_PAPI.state';
/**
* The key of the AuthId field in the state.
*/
const AUTHID = 'sspmod_papi_Auth_Source_PAPI.AuthId';
/**
* @var the PoA to use.
*/
private $_poa;
/**
* @var the home locator interface to use.
*/
private $_hli;
/**
* @var the PAPIOPOA to use.
*/
private $_papiopoa;
/**
* @var the attributes of the user.
*/
private $_attrs;
/**
* @var the state ID to retrieve the original request later.
*/
private $_stateId;
/**
* Constructor for this authentication source.
*
* @param array $info Information about this authentication source.
* @param array $config Configuration.
*/
public function __construct($info, $config) {
assert('is_array($info)');
assert('is_array($config)');
/* Call the parent constructor first, as required by the interface. */
parent::__construct($info, $config);
if (!array_key_exists('site', $config)) {
throw new Exception('PAPI authentication source is not properly configured: missing [site]');
}
$this->_poa = new PoA($config['site']);
if (array_key_exists('hli', $config)) {
$this->_hli = $config['hli'];
}
}
/**
* Hook that will set Home Locator Identifier, PAPIOPOA and/or State ID.
*
* @param The PAPI request parameters that will be modified/extended.
*/
public function modifyParams(&$params) {
if (!empty($this->_hli)) {
$params['PAPIHLI'] = $this->_hli;
}
if (!empty($this->_papiopoa)) {
$params['PAPIOPOA'] = $this->_papiopoa;
}
$params['URL'] = $params['URL'].urlencode("&SSPStateID=".$this->_stateId);
return false;
}
/**
* Parse the attribute array in a format suitable for SSP.
*
* @param the original attribute array.
*/
protected function parseAttributes($attrs) {
assert('is_array($attrs)');
foreach ($attrs as $name => $value) {
if (!is_array($value)) {
$attrs[$name] = array($value);
}
}
return $attrs;
}
/**
* Log-in using PAPI
*
* @param array &$state Information about the current authentication.
*/
public function authenticate(&$state) {
assert('is_array($state)');
$this->_papiopoa = $state['SPMetadata']['entityid'];
// check if we are returning back from PAPI authentication
if (isset($_REQUEST['SSPStateID'])) {
// yes! restore original request
$this->_stateId = (string)$_REQUEST['SSPStateID'];
// sanitize the input
$sid = SimpleSAML_Utilities::parseStateID($this->_stateId);
if (!is_null($sid['url'])) {
SimpleSAML_Utilities::checkURLAllowed($sid['url']);
}
$state = SimpleSAML_Auth_State::loadState($this->_stateId, self::STAGE_INIT);
} else if (!$this->_poa->isAuthenticated()) {
// no! we have to save the request
/* We are will need the authId in order to retrieve this authentication source later. */
$state[self::AUTHID] = $this->authId;
$this->_stateId = SimpleSAML_Auth_State::saveState($state, self::STAGE_INIT);
$this->_poa->addHook("PAPI_REDIRECT_URL_FINISH", new Hook(array($this, "modifyParams")));
}
$this->_poa->authenticate();
$this->_attrs = $this->_poa->getAttributes();
$state['Attributes'] = $this->parseAttributes($this->_attrs);
self::completeAuth($state);
}
/**
* Log out from this authentication source.
*
* This function should be overridden if the authentication source requires special
* steps to complete a logout operation.
*
* If the logout process requires a redirect, the state should be saved. Once the
* logout operation is completed, the state should be restored, and completeLogout
* should be called with the state. If this operation can be completed without
* showing the user a page, or redirecting, this function should return.
*
* @param array &$state Information about the current logout operation.
*/
public function logout(&$state) {
assert('is_array($state)');
// check first if we have a valid session
if ($this->_poa->isAuthenticated()) {
/* We are will need the authId in order to retrieve this authentication source later. */
$state[self::AUTHID] = $this->authId;
$this->_stateId = SimpleSAML_Auth_State::saveState($state, self::STAGE_INIT);
// TODO: pending on phpPoA adding PAPI_SLO_REDIRECT_URL_FINISH hook
$this->_poa->addHook("PAPI_SLO_REDIRECT_URL_FINISH", new Hook(array($this, "modifyParams")));
// perform single logout, this won't return
$this->_poa->logout(true);
} else if (isset($_REQUEST['SSPStateID'])) {
$this->_stateId = (string)$_REQUEST['SSPStateID'];
// sanitize the input
$sid = SimpleSAML_Utilities::parseStateID($this->_stateId);
if (!is_null($sid['url'])) {
SimpleSAML_Utilities::checkURLAllowed($sid['url']);
}
$state = SimpleSAML_Auth_State::loadState($this->_stateId, self::STAGE_INIT);
} else {
return;
}
self::completeLogout($state);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment