<?php
/**
* WARNING:
*
* THIS FILE IS DEPRECATED AND WILL BE REMOVED IN FUTURE VERSIONS
*
* @deprecated
*/
/**
* WS-Federation/ADFS PRP protocol support for simpleSAMLphp.
*
* The AssertionConsumerService handler accepts responses from a WS-Federation
* Account Partner using the Passive Requestor Profile (PRP) and handles it as
* a Resource Partner. It receives a response, parses it and passes on the
* authentication+attributes.
*
* @author Hans Zandbelt, SURFnet BV. <hans.zandbelt@surfnet.nl>
* @package simpleSAMLphp
*/
require_once('../../_include.php');
$config = SimpleSAML_Configuration::getInstance();
$session = SimpleSAML_Session::getSessionFromRequest();
$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
SimpleSAML_Logger::warning('The file wsfed/sp/prp.php is deprecated and will be removed in future versions.');
SimpleSAML_Logger::info('WS-Fed - SP.AssertionConsumerService: Accessing WS-Fed SP endpoint AssertionConsumerService');
if (!$config->getBoolean('enable.wsfed-sp', false))
throw new SimpleSAML_Error_Error('NOACCESS');
if (!empty($_GET['wa']) and ($_GET['wa'] == 'wsignoutcleanup1.0')) {
if (isset($session) && $session->isValid('wsfed')) {
$session->doLogout('wsfed');
}
if (!empty($_GET['wreply'])) {
SimpleSAML_Utilities::redirectUntrustedURL(urldecode($_GET['wreply']));
}
exit;
}
/* Make sure that the correct query parameters are passed to this script. */
try {
if (empty($_POST['wresult'])) {
throw new Exception('Missing wresult parameter');
}
if (empty($_POST['wa'])) {
throw new Exception('Missing wa parameter');
}
if (empty($_POST['wctx'])) {
throw new Exception('Missing wctx parameter');
}
} catch(Exception $exception) {
throw new SimpleSAML_Error_Error('ACSPARAMS', $exception);
}
try {
$wa = $_POST['wa'];
$wresult = $_POST['wresult'];
$wctx = $_POST['wctx'];
/* Load and parse the XML. */
$dom = new DOMDocument();
/* Accommodate for MS-ADFS escaped quotes */
$wresult = str_replace('\"', '"', $wresult);
$dom->loadXML(str_replace ("\r", "", $wresult));
$xpath = new DOMXpath($dom);
$xpath->registerNamespace('wst', 'http://schemas.xmlsoap.org/ws/2005/02/trust');
$xpath->registerNamespace('saml', 'urn:oasis:names:tc:SAML:1.0:assertion');
/* Find the saml:Assertion element in the response. */
$assertions = $xpath->query('/wst:RequestSecurityTokenResponse/wst:RequestedSecurityToken/saml:Assertion');
if ($assertions->length === 0) {
throw new Exception('Received a response without an assertion on the WS-Fed PRP handler.');
}
if ($assertions->length > 1) {
throw new Exception('The WS-Fed PRP handler currently only supports a single assertion in a response.');
}
$assertion = $assertions->item(0);
/* Find the entity id of the issuer. */
$idpEntityId = $assertion->getAttribute('Issuer');
/* Load the IdP metadata. */
$idpMetadata = $metadata->getMetaData($idpEntityId, 'wsfed-idp-remote');
/* Find the certificate used by the IdP. */
if(array_key_exists('certificate', $idpMetadata)) {
$certFile = SimpleSAML_Utilities::resolveCert($idpMetadata['certificate']);
} else {
throw new Exception('Missing \'certificate\' metadata option in the \'wsfed-idp-remote\' metadata' .
' for the IdP \'' . $idpEntityId . '\'.');
}
/* Load the certificate. */
$certData = file_get_contents($certFile);
if($certData === FALSE) {
throw new Exception('Unable to load certificate file \'' . $certFile . '\' for wsfed-idp \'' .
$idpEntityId . '\'.');
}
/* Verify that the assertion is signed by the issuer. */
$validator = new SimpleSAML_XML_Validator($assertion, 'AssertionID', $certData);
if(!$validator->isNodeValidated($assertion)) {
throw new Exception('The assertion was not correctly signed by the WS-Fed IdP \'' .
$idpEntityId . '\'.');
}
/* Check time constraints of contitions (if present). */
foreach($xpath->query('./saml:Conditions', $assertion) as $condition) {
$notBefore = $condition->getAttribute('NotBefore');
$notOnOrAfter = $condition->getAttribute('NotOnOrAfter');
if(!SimpleSAML_Utilities::checkDateConditions($notBefore, $notOnOrAfter)) {
throw new Exception('The response has expired.');
}
}
/* Extract the name identifier from the response. */
$nameid = $xpath->query('./saml:AuthenticationStatement/saml:Subject/saml:NameIdentifier', $assertion);
if ($nameid->length === 0) {
throw new Exception('Could not find the name identifier in the response from the WS-Fed IdP \'' .
$idpEntityId . '\'.');
}
$nameid = array(
'Format' => $nameid->item(0)->getAttribute('Format'),
'Value' => $nameid->item(0)->textContent,
);
/* Extract the attributes from the response. */
$attributes = array();
$attributeValues = $xpath->query('./saml:AttributeStatement/saml:Attribute/saml:AttributeValue', $assertion);
foreach($attributeValues as $attribute) {
$name = $attribute->parentNode->getAttribute('AttributeName');
$value = $attribute->textContent;
if(!array_key_exists($name, $attributes)) {
$attributes[$name] = array();
}
$attributes[$name][] = $value;
}
/* Mark the user as logged in. */
$authData = array(
'Attributes' => $attributes,
'saml:sp:NameID' => $nameid,
'saml:sp:IdP' => $idpEntityId,
);
$session->doLogin('wsfed', $authData);
/* Redirect the user back to the page which requested the login. */
SimpleSAML_Utilities::redirectUntrustedURL($wctx);
} catch(Exception $exception) {
throw new SimpleSAML_Error_Error('PROCESSASSERTION', $exception);
}
?>
|