Skip to content
Snippets Groups Projects
Commit 8878597d authored by Olav Morken's avatar Olav Morken
Browse files

Experimental SAML 2.0 SP authentication source.

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@949 44740490-163a-0410-bde0-09ae8108e29a
parent af6ff88f
No related branches found
No related tags found
No related merge requests found
This file indicates that the default state of this module
is enabled. To disable, create a file named disable in the
same directory as this file.
<?php
/**
* SAML 2.0 SP authentication client.
*
* Example:
* 'example-openidp' => array(
* 'saml2:SP',
* 'idp' => 'https://openidp.feide.no',
* ),
*
* @package simpleSAMLphp
* @version $Id$
*/
class sspmod_saml2_Auth_Source_SP extends SimpleSAML_Auth_Source {
/**
* The string used to identify our states.
*/
const STAGE_SENT = 'saml2:SP-SSOSent';
/**
* The key of the AuthId field in the state.
*/
const AUTHID = 'saml2:AuthId';
/**
* The entity id of this SP.
*/
private $entityId;
/**
* The entity id of the IdP we connect to.
*/
private $idp;
/**
* Constructor for SAML 2.0 SP 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('entityId', $config)) {
$this->entityId = $config['entityId'];
} else {
$this->entityId = SimpleSAML_Module::getModuleURL('saml2/sp/metadata.php?source=' .
urlencode($this->authId) . '&tmp');
}
if (array_key_exists('idp', $config)) {
$this->idp = $config['idp'];
} else {
throw new Exception('TODO: Add support for IdP discovery.');
}
}
/**
* Start login.
*
* This function saves the information about the login, and redirects to the IdP.
*
* @param array &$state Information about the current authentication.
*/
public function authenticate(&$state) {
assert('is_array($state)');
/* We are going to need the authId in order to retrieve this authentication source later. */
$state[self::AUTHID] = $this->authId;
$id = SimpleSAML_Auth_State::saveState($state, self::STAGE_SENT);
$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
$idpMetadata = $metadata->getMetaData($this->idp, 'saml20-idp-remote');
$config = SimpleSAML_Configuration::getInstance();
$sr = new SimpleSAML_XML_SAML20_AuthnRequest($config, $metadata);
$req = $sr->generate($this->entityId, $idpMetadata['SingleSignOnService']);
$httpredirect = new SimpleSAML_Bindings_SAML20_HTTPRedirect($config, $metadata);
$httpredirect->sendMessage($req, $this->entityid, $this->idp, $id);
exit(0);
}
/**
* Retrieve the entity id of this SP.
*
* @return string Entity id of this SP.
*/
public function getEntityId() {
return $this->entityId;
}
}
?>
\ No newline at end of file
<?php
/**
* Assertion consumer service handler for SAML 2.0 SP authentication client.
*/
if (!array_key_exists('SAMLResponse', $_POST)) {
throw new SimpleSAML_Error_BadRequest('Missing SAMLResponse to AssertionConsumerService');
}
if (!array_key_exists('RelayState', $_POST)) {
throw new SimpleSAML_Error_BadRequest('Missing RelayState to AssertionConsumerService');
}
$state = SimpleSAML_Auth_State::loadState($_POST['RelayState'], sspmod_saml2_Auth_Source_SP::STAGE_SENT);
/* Find authentication source. */
assert('array_key_exists(sspmod_saml2_Auth_Source_SP::AUTHID, $state)');
$sourceId = $state[sspmod_saml2_Auth_Source_SP::AUTHID];
$source = SimpleSAML_Auth_Source::getById($sourceId);
if ($source === NULL) {
throw new Exception('Could not find authentication source with id ' . $sourceId);
}
$config = SimpleSAML_Configuration::getInstance();
$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
$binding = new SimpleSAML_Bindings_SAML20_HTTPPost($config, $metadata);
$authnResponse = $binding->decodeResponse($_POST);
$result = $authnResponse->process();
/* Check status code. */
if($result === FALSE) {
/* Not successful. */
$statusCode = $authnResponse->findstatus();
throw new Exception('Error authenticating: ' . $statusCode);
}
/* The response should include the entity id of the IdP. */
$idp = $authnResponse->getIssuer();
/* TODO: Check that IdP is the correct IdP. */
/* TODO: Save NameID & SessionIndex for logout. */
$state['Attributes'] = $authnResponse->getAttributes();
SimpleSAML_Auth_Source::completeAuth($state);
?>
\ No newline at end of file
<?php
if (!array_key_exists('source', $_GET)) {
throw new SimpleSAML_Error_BadRequest('Missing source parameter');
}
$sourceId = $_GET['source'];
$source = SimpleSAML_Auth_Source::getById($sourceId);
if ($source === NULL) {
throw new SimpleSAML_Error_NotFound('Could not find authentication source with id ' . $sourceId);
}
if (!($source instanceof sspmod_saml2_Auth_Source_SP)) {
throw new SimpleSAML_Error_NotFound('Source isn\'t a SAML 2.0 SP: ' . $sourceId);
}
$entityId = $source->getEntityId();
$metaArray = array(
'AssertionConsumerService' => SimpleSAML_Module::getModuleURL('saml2/sp/acs.php'),
);
$metaBuilder = new SimpleSAML_Metadata_SAMLBuilder($entityId);
$metaBuilder->addMetadataSP20($metaArray);
$config = SimpleSAML_Configuration::getInstance();
$metaBuilder->addContact('technical', array(
'emailAddress' => $config->getValue('technicalcontact_email'),
'name' => $config->getValue('technicalcontact_name'),
));
$xml = $metaBuilder->getEntityDescriptorText();
echo($xml);
?>
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