summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/papi/default-disable0
-rw-r--r--modules/papi/docs/papi.txt43
-rw-r--r--modules/papi/lib/Auth/Source/PAPI.php174
3 files changed, 217 insertions, 0 deletions
diff --git a/modules/papi/default-disable b/modules/papi/default-disable
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/modules/papi/default-disable
diff --git a/modules/papi/docs/papi.txt b/modules/papi/docs/papi.txt
new file mode 100644
index 0000000..2180206
--- /dev/null
+++ b/modules/papi/docs/papi.txt
@@ -0,0 +1,43 @@
+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
diff --git a/modules/papi/lib/Auth/Source/PAPI.php b/modules/papi/lib/Auth/Source/PAPI.php
new file mode 100644
index 0000000..ead66c8
--- /dev/null
+++ b/modules/papi/lib/Auth/Source/PAPI.php
@@ -0,0 +1,174 @@
+<?php
+
+/**
+ * Authenticate using PAPI protocol.
+ *
+ * @author Jaime Perez, RedIRIS
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+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'];
+ $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'];
+ $state = SimpleSAML_Auth_State::loadState($this->_stateId, self::STAGE_INIT);
+ } else {
+ return;
+ }
+
+ self::completeLogout($state);
+ }
+
+}
+
+?>