diff --git a/config-templates/config.php b/config-templates/config.php index 2fb856d782ddd5238d621aaeb28be673ca5c403c..4e0ca044c7a152d26f6ae530011d5292e7e1bee6 100644 --- a/config-templates/config.php +++ b/config-templates/config.php @@ -126,6 +126,7 @@ $config = array ( */ 'enable.saml20-idp' => false, 'enable.shib13-idp' => false, + 'enable.adfs-idp' => false, 'enable.wsfed-sp' => false, 'enable.authmemcookie' => false, diff --git a/lib/SimpleSAML/IdP.php b/lib/SimpleSAML/IdP.php index 0009af754272ec872d9983c453de887ada594a2f..b7ab3bc1a270f88f2d1727c527a188c89f0bd6a8 100644 --- a/lib/SimpleSAML/IdP.php +++ b/lib/SimpleSAML/IdP.php @@ -57,6 +57,11 @@ class SimpleSAML_IdP { throw new SimpleSAML_Error_Exception('enable.shib13-idp disabled in config.php.'); } $this->config = $metadata->getMetaDataConfig(substr($id, 6), 'shib13-idp-hosted'); + } elseif (substr($id, 0, 5) === 'adfs:') { + if (!$globalConfig->getBoolean('enable.adfs-idp', FALSE)) { + throw new SimpleSAML_Error_Exception('enable.adfs-idp disabled in config.php.'); + } + $this->config = $metadata->getMetaDataConfig(substr($id, 5), 'adfs-idp-hosted'); } else { assert(FALSE); } diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatFile.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatFile.php index 2fbc6ca72362f3847e6aee7846ce41a5a2bf27ba..64f4624480505dff8c8b453e85dc79308d791470 100644 --- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatFile.php +++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatFile.php @@ -130,6 +130,8 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerFlatFile extends SimpleSAML_Meta return $baseurl . 'shib13/sp/metadata.php'; } elseif($set === 'wsfed-sp-hosted') { return 'urn:federation:' . SimpleSAML_Utilities::getSelfHost(); + } elseif($set === 'adfs-idp-hosted') { + return 'urn:federation:' . SimpleSAML_Utilities::getSelfHost() . ':idp'; } else { throw new Exception('Can not generate dynamic EntityID for metadata of this type: [' . $set . ']'); } diff --git a/metadata-templates/adfs-idp-hosted.php b/metadata-templates/adfs-idp-hosted.php new file mode 100644 index 0000000000000000000000000000000000000000..040a199aa2665faa7ebb0f5e5f6c315d5d1cdb96 --- /dev/null +++ b/metadata-templates/adfs-idp-hosted.php @@ -0,0 +1,10 @@ +<?php + +$metadata['__DYNAMIC:1__'] = array( + 'host' => '__DEFAULT__', + 'privatekey' => 'server.pem', + 'certificate' => 'server.crt', + 'auth' => 'example-userpass', +); + +?> diff --git a/metadata-templates/adfs-sp-remote.php b/metadata-templates/adfs-sp-remote.php new file mode 100644 index 0000000000000000000000000000000000000000..373a6689f58f360984df0cee71a95e90284bcb1f --- /dev/null +++ b/metadata-templates/adfs-sp-remote.php @@ -0,0 +1,14 @@ +<?php + +$metadata['urn:federation:localhost'] = array( + 'prp' => 'https://localhost/adfs/ls/', + 'simplesaml.nameidattribute' => 'uid', + 'authproc' => array( + 50 => array( + 'class' => 'core:AttributeLimit', + 'cn', 'mail', 'uid', 'eduPersonAffiliation', + ), + ), +); + +?> diff --git a/modules/adfs/lib/IdP/ADFS.php b/modules/adfs/lib/IdP/ADFS.php new file mode 100644 index 0000000000000000000000000000000000000000..da55aa28a832d52f50db049250e192f1cc00c887 --- /dev/null +++ b/modules/adfs/lib/IdP/ADFS.php @@ -0,0 +1,199 @@ +<?php + +class sspmod_adfs_IdP_ADFS { + + public static function receiveAuthnRequest(SimpleSAML_IdP $idp) { + try { + // accomodate for disfunctional $_GET "windows" slash decoding in PHP + $wctx = $_GET['wctx']; + foreach (explode('&', $_SERVER['REQUEST_URI']) as $e) { + $a = explode('=', $e); + if ($a[0] == 'wctx') $wctx = urldecode($a[1]); + } + $requestid = $wctx; + $issuer = $_GET['wtrealm']; + $requestcache = array( + 'RequestID' => $requestid, + 'Issuer' => $issuer, + 'RelayState' => $requestid + ); + + $spEntityId = $requestcache['Issuer']; + $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); + $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'adfs-sp-remote'); + + SimpleSAML_Logger::info('ADFS - IdP.prp: Incoming Authentication request: '.$issuer.' id '.$requestid); + + } catch(Exception $exception) { + SimpleSAML_Utilities::fatalError($session->getTrackID(), 'PROCESSAUTHNREQUEST', $exception); + } + + $sessionLostURL = NULL; // TODO? + $forceAuthn = FALSE; + $isPassive = FALSE; + + $state = array( + 'Responder' => array('sspmod_adfs_IdP_ADFS', 'sendResponse'), +// SimpleSAML_Auth_State::EXCEPTION_HANDLER_FUNC => array('sspmod_adfs_IdP', 'handleAuthError'), +// SimpleSAML_Auth_State::RESTART => $sessionLostURL, + 'SPMetadata' => $spMetadata->toArray(), + 'ForceAuthn' => $forceAuthn, + 'isPassive' => $isPassive, + 'adfs:wctx' => $wctx, + ); + + $idp->handleAuthenticationRequest($state); + } + + public static function ADFS_GenerateResponse($issuer, $target, $nameid, $attributes) { + #$nameid = 'hans@surfnet.nl'; + $issueInstant = SimpleSAML_Utilities::generateTimestamp(); + $notBefore = SimpleSAML_Utilities::generateTimestamp(time() - 30); + $assertionExpire = SimpleSAML_Utilities::generateTimestamp(time() + 60 * 5); + $assertionID = SimpleSAML_Utilities::generateID(); + $nameidFormat = 'http://schemas.xmlsoap.org/claims/UPN'; + $result = +'<wst:RequestSecurityTokenResponse xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust"> + <wst:RequestedSecurityToken> + <saml:Assertion Issuer="' . $issuer . '" IssueInstant="' . $issueInstant . '" AssertionID="' . $assertionID . '" MinorVersion="1" MajorVersion="1" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"> + <saml:Conditions NotOnOrAfter="' . $assertionExpire . '" NotBefore="' . $notBefore . '"> + <saml:AudienceRestrictionCondition> + <saml:Audience>' . $target .'</saml:Audience> + </saml:AudienceRestrictionCondition> + </saml:Conditions> + <saml:AuthenticationStatement AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:unspecified" AuthenticationInstant="' . $issueInstant . '"> + <saml:Subject> + <saml:NameIdentifier Format="' . $nameidFormat . '">' . htmlspecialchars($nameid) . '</saml:NameIdentifier> + </saml:Subject> + </saml:AuthenticationStatement> + <saml:AttributeStatement> + <saml:Subject> + <saml:NameIdentifier Format="' . $nameidFormat . '">' . htmlspecialchars($nameid) . '</saml:NameIdentifier> + </saml:Subject>'; + foreach ($attributes as $name => $values) { + if ((!is_array($values)) || (count($values) == 0)) continue; + $hasValue = FALSE; + $r = '<saml:Attribute AttributeNamespace="http://schemas.xmlsoap.org/claims" AttributeName="' . htmlspecialchars($name) .'">'; + foreach ($values as $value) { + if ( (!isset($value)) or ($value === '')) continue; + $r .= '<saml:AttributeValue>' . htmlspecialchars($value) . '</saml:AttributeValue>'; + $hasValue = TRUE; + } + $r .= '</saml:Attribute>'; + if ($hasValue) $result .= $r; + } + $result .= ' + </saml:AttributeStatement> + </saml:Assertion> + </wst:RequestedSecurityToken> + <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"><wsa:EndpointReference xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"> + <wsa:Address>' . $target . '</wsa:Address> + </wsa:EndpointReference></wsp:AppliesTo> + </wst:RequestSecurityTokenResponse>'; + return $result; + } + + public static function ADFS_SignResponse($response, $key, $cert) { + $objXMLSecDSig = new XMLSecurityDSig(); + $objXMLSecDSig->idKeys = array('AssertionID'); + $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); + $responsedom = new DOMDocument(); + $responsedom->loadXML(str_replace ("\r", "", $response)); + $firstassertionroot = $responsedom->getElementsByTagName('Assertion')->item(0); + $objXMLSecDSig->addReferenceList(array($firstassertionroot), XMLSecurityDSig::SHA1, + array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), + array('id_name' => 'AssertionID')); + $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type'=>'private')); + $objKey->loadKey($key, TRUE); + $objXMLSecDSig->sign($objKey); + if ($cert) { + $public_cert = file_get_contents($cert); + $objXMLSecDSig->add509Cert($public_cert, TRUE); + } + $newSig = $responsedom->importNode($objXMLSecDSig->sigNode, TRUE); + $firstassertionroot->appendChild($newSig); + return $responsedom->saveXML(); + } + + public static function ADFS_PostResponse($url, $wresult, $wctx) { + print ' +<body onload="document.forms[0].submit()"><form method="post" action="' . $url . '"> + <input type="hidden" name="wa" value="wsignin1.0"> + <input type="hidden" name="wresult" value="' . htmlspecialchars($wresult) . '"> + <input type="hidden" name="wctx" value="' . htmlspecialchars($wctx) . '"> + <noscript><input type="submit" value="Continue"></noscript> +</form></body>'; + exit; + } + + public static function sendResponse(array $state) { + $spMetadata = $state["SPMetadata"]; + $spEntityId = $spMetadata['entityid']; + $spMetadata = SimpleSAML_Configuration::loadFromArray($spMetadata, + '$metadata[' . var_export($spEntityId, TRUE) . ']'); + + $attributes = $state['Attributes']; + + $nameidattribute = $spMetadata->getValue('simplesaml.nameidattribute'); + if (!empty($nameidattribute)) { + if (!array_key_exists($nameidattribute, $attributes)) { + throw new Exception('simplesaml.nameidattribute does not exist in resulting attribute set'); + } + $nameid = $attributes[$nameidattribute][0]; + } else { + $nameid = SimpleSAML_Utilities::generateID(); + } + + $idp = SimpleSAML_IdP::getByState($state); + $idpMetadata = $idp->getConfig(); + $idpEntityId = $idpMetadata->getString('entityid'); + + $idp->addAssociation(array( + 'id' => 'adfs:' . $spEntityId, + 'Handler' => 'sspmod_adfs_IdP_ADFS', + 'adfs:entityID' => $spEntityId, + )); + + $response = sspmod_adfs_IdP_ADFS::ADFS_GenerateResponse($idpEntityId, $spEntityId, $nameid, $attributes); + + $config = SimpleSAML_Configuration::getInstance(); + $certdir = $config->getPathValue('certdir', 'cert/'); + $wresult = sspmod_adfs_IdP_ADFS::ADFS_SignResponse($response, $certdir . $idpMetadata->getString('privatekey'), $certdir . $idpMetadata->getString('certificate')); + + $wctx = $state['adfs:wctx']; + sspmod_adfs_IdP_ADFS::ADFS_PostResponse($spMetadata->getValue('prp'), $wresult, $wctx); + } +/* + public static function handleAuthError(SimpleSAML_Error_Exception $exception, array $state) { + } +*/ + public static function sendLogoutResponse(SimpleSAML_IdP $idp, array $state) { + // NB:: we don't know from which SP the logout request came from + $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); + $idpMetadata = $idp->getConfig(); + SimpleSAML_Utilities::redirect($idpMetadata->getValue('redirect-after-logout', SimpleSAML_Utilities::getBaseURL())); + } + + public static function receiveLogoutMessage(SimpleSAML_IdP $idp) { + $state = array( + 'Responder' => array('sspmod_adfs_IdP_ADFS', 'sendLogoutResponse'), + ); + //$spEntityId = NULL; + //$assocId = 'adfs:' . $spEntityId; + $assocId = NULL; + // TODO: verify that this is really no problem for: + // a) SSP, because there's no caller SP... + // b) ADFS SP because caller will be called back... + $idp->handleLogoutRequest($state, $assocId); + } + + // accepts an association array, and returns an URL that can be accessed to terminate the association. + public static function getLogoutURL(SimpleSAML_IdP $idp, array $association, $relayState) { + $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); + $idpMetadata = $idp->getConfig(); + $spMetadata = $metadata->getMetaDataConfig($association['adfs:entityID'], 'adfs-sp-remote'); + // 'https://adfs-test.showcase.surfnet.nl/adfs/ls/?wa=wsignoutcleanup1.0&wreply=https%3A%2F%2Flocalhost%2Fsimplesaml'); + $returnTo = SimpleSAML_Module::getModuleURL('adfs/idp/prp.php?assocId=' . urlencode($association["id"]) . '&relayState=' . urlencode($relayState)); + return $spMetadata->getValue('prp') . '?' . 'wa=wsignoutcleanup1.0&wreply=' . urlencode($returnTo); + } +} diff --git a/modules/adfs/www/idp/prp.php b/modules/adfs/www/idp/prp.php index 3b38ccb448d068440c8930eae3e7223c120d1821..c6f545e33c62745b86b7e1d74996108d1ceee28c 100644 --- a/modules/adfs/www/idp/prp.php +++ b/modules/adfs/www/idp/prp.php @@ -2,274 +2,30 @@ /** * ADFS PRP IDP protocol support for simpleSAMLphp. * - * @author Hans Zandbelt, SURFnet BV. <hans.zandbelt@surfnet.nl> + * @author Hans Zandbelt, SURFnet bv, <hans.zandbelt@surfnet.nl> * @package simpleSAMLphp * @version $Id$ */ -$config = SimpleSAML_Configuration::getInstance(); -$adfsconfig = SimpleSAML_Configuration::getConfig('adfs-idp-hosted.php'); -$session = SimpleSAML_Session::getInstance(); +SimpleSAML_Logger::info('ADFS - IdP.prp: Accessing ADFS IdP endpoint prp'); -SimpleSAML_Logger::info('ADFS - IdP.SSOService: Accessing ADFS IdP endpoint SSOService'); - -try { - if (array_key_exists('entityId', $config)) { - $idpentityid = $config['entityId']; - } else { - $idpentityid = 'urn:federation:' . SimpleSAML_Utilities::getSelfHost() . ':idp'; - } -} catch (Exception $exception) { - SimpleSAML_Utilities::fatalError($session->getTrackID(), 'METADATA', $exception); -} - -SimpleSAML_Logger::info('ADFS - IdP.SSOService: Accessing ADFS IdP endpoint SSOService'); - -function ADFS_GenerateResponse($issuer, $target, $nameid, $attributes) { -# $nameid = 'hans@surfnet.nl'; - $issueInstant = SimpleSAML_Utilities::generateTimestamp(); - $notBefore = SimpleSAML_Utilities::generateTimestamp(time() - 30); - $assertionExpire = SimpleSAML_Utilities::generateTimestamp(time() + 60 * 5); - $assertionID = SimpleSAML_Utilities::generateID(); - $nameidFormat = 'http://schemas.xmlsoap.org/claims/UPN'; - $result = -'<wst:RequestSecurityTokenResponse xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust"> - <wst:RequestedSecurityToken> - <saml:Assertion Issuer="' . $issuer . '" IssueInstant="' . $issueInstant . '" AssertionID="' . $assertionID . '" MinorVersion="1" MajorVersion="1" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"> - <saml:Conditions NotOnOrAfter="' . $assertionExpire . '" NotBefore="' . $notBefore . '"> - <saml:AudienceRestrictionCondition> - <saml:Audience>' . $target .'</saml:Audience> - </saml:AudienceRestrictionCondition> - </saml:Conditions> - <saml:AuthenticationStatement AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:unspecified" AuthenticationInstant="' . $issueInstant . '"> - <saml:Subject> - <saml:NameIdentifier Format="' . $nameidFormat . '">' . htmlspecialchars($nameid) . '</saml:NameIdentifier> - </saml:Subject> - </saml:AuthenticationStatement> - <saml:AttributeStatement> - <saml:Subject> - <saml:NameIdentifier Format="' . $nameidFormat . '">' . htmlspecialchars($nameid) . '</saml:NameIdentifier> - </saml:Subject>'; - foreach ($attributes as $name => $values) { - if ((!is_array($values)) || (count($values) == 0)) continue; - $hasValue = FALSE; - $r = '<saml:Attribute AttributeNamespace="http://schemas.xmlsoap.org/claims" AttributeName="' . htmlspecialchars($name) .'">'; - foreach ($values as $value) { - if ( (!isset($value)) or ($value === '')) continue; - $r .= '<saml:AttributeValue>' . htmlspecialchars($value) . '</saml:AttributeValue>'; - $hasValue = TRUE; - } - $r .= '</saml:Attribute>'; - if ($hasValue) $result .= $r; - } - $result .= ' - </saml:AttributeStatement> - </saml:Assertion> - </wst:RequestedSecurityToken> - <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"><wsa:EndpointReference xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"> - <wsa:Address>' . $target . '</wsa:Address> - </wsa:EndpointReference></wsp:AppliesTo> - </wst:RequestSecurityTokenResponse>'; - return $result; -} - -function ADFS_SignResponse($response, $key, $cert) { - $objXMLSecDSig = new XMLSecurityDSig(); - $objXMLSecDSig->idKeys = array('AssertionID'); - $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); - $responsedom = new DOMDocument(); - $responsedom->loadXML(str_replace ("\r", "", $response)); - $firstassertionroot = $responsedom->getElementsByTagName('Assertion')->item(0); - $objXMLSecDSig->addReferenceList(array($firstassertionroot), XMLSecurityDSig::SHA1, - array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), - array('id_name' => 'AssertionID')); - $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type'=>'private')); - $objKey->loadKey($key, TRUE); - $objXMLSecDSig->sign($objKey); - if ($cert) { - $public_cert = file_get_contents($cert); - $objXMLSecDSig->add509Cert($public_cert, TRUE); - } - $newSig = $responsedom->importNode($objXMLSecDSig->sigNode, TRUE); - $firstassertionroot->appendChild($newSig); - return $responsedom->saveXML(); -} - -function ADFS_PostResponse($url, $wresult, $wctx) { - print ' -<body onload="document.forms[0].submit()"><form method="post" action="' . $url . '"> - <input type="hidden" name="wa" value="wsignin1.0"> - <input type="hidden" name="wresult" value="' . htmlspecialchars($wresult) . '"> - <input type="hidden" name="wctx" value="' . htmlspecialchars($wctx) . '"> - <noscript><input type="submit" value="Continue"></noscript> -</form></body>'; - exit; -} +$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); +$idpEntityId = $metadata->getMetaDataCurrentEntityID('adfs-idp-hosted'); +$idp = SimpleSAML_IdP::getById('adfs:' . $idpEntityId); if (isset($_GET['wa'])) { - - if ($_GET['wa'] == 'wsignin1.0') { - try { - // accomodate for disfunctional $_GET "windows" slash decoding in PHP - $wctx = $_GET['wctx']; - foreach (explode('&', $_SERVER['REQUEST_URI']) as $e) { - $a = explode('=', $e); - if ($a[0] == 'wctx') $wctx = urldecode($a[1]); - } - $requestid = $wctx; - $issuer = $_GET['wtrealm']; - $requestcache = array( - 'RequestID' => $requestid, - 'Issuer' => $issuer, - 'RelayState' => $requestid - ); - - $spentityid = $requestcache['Issuer']; - - SimpleSAML_Logger::info('ADFS - IdP.SSOService: Incoming Authentication request: '.$issuer.' id '.$requestid); - - } catch(Exception $exception) { - SimpleSAML_Utilities::fatalError($session->getTrackID(), 'PROCESSAUTHNREQUEST', $exception); - } - } - -} elseif(isset($_GET['RequestID'])) { - - try { - - SimpleSAML_Logger::info('ADFS - IdP.SSOService: Got incoming authentication ID'); - - $authId = $_GET['RequestID']; - $requestcache = $session->getAuthnRequest('adfs', $authId); - if (!$requestcache) { - throw new Exception('Could not retrieve cached RequestID = ' . $authId); - } - - } catch(Exception $exception) { - SimpleSAML_Utilities::fatalError($session->getTrackID(), 'CACHEAUTHNREQUEST', $exception); - } - -} elseif(isset($_REQUEST[SimpleSAML_Auth_ProcessingChain::AUTHPARAM])) { - - $authProcId = $_REQUEST[SimpleSAML_Auth_ProcessingChain::AUTHPARAM]; - $authProcState = SimpleSAML_Auth_ProcessingChain::fetchProcessedState($authProcId); - $requestcache = $authProcState['core:adfs-idp:requestcache']; - -} else { - SimpleSAML_Utilities::fatalError($session->getTrackID(), 'SSOSERVICEPARAMS'); -} - -if(SimpleSAML_Auth_Source::getById($adfsconfig->getValue('auth')) !== NULL) { - $authSource = TRUE; - $authority = $adfsconfig->getValue('auth'); -} else { - $authSource = FALSE; - $authority = $adfsconfig->getValue('authority'); -} - -if (!$session->isValid($authority) ) { - - SimpleSAML_Logger::info('ADFS - IdP.SSOService: Will go to authentication module ' . $adfsconfig->getValue('auth')); - - $authId = SimpleSAML_Utilities::generateID(); - $session->setAuthnRequest('adfs', $authId, $requestcache); - - $redirectTo = SimpleSAML_Utilities::selfURLNoQuery() . '?RequestID=' . urlencode($authId); - - if($authSource) { - - SimpleSAML_Auth_Default::initLogin($adfsconfig->getValue('auth'), $redirectTo); - } else { - $authurl = '/' . $config->getBaseURL() . $adfsconfig->getValue('auth'); - - SimpleSAML_Utilities::redirect($authurl, array( - 'RelayState' => $redirectTo, - 'AuthId' => $authId, - 'protocol' => 'adfs', - )); - } - -} else { - - try { - - $spentityid = $requestcache['Issuer']; - $spmetadata = SimpleSAML_Configuration::getConfig('adfs-sp-remote.php'); - - $arr = $spmetadata->getValue($spentityid); - if (!isset($arr)) { - throw new Exception('Metadata for ADFS SP "' . $spentityid . '" could not be found in adfs-sp-remote.php!'); - } - $spmetadata = SimpleSAML_Configuration::loadFromArray($arr); - - SimpleSAML_Logger::info('ADFS - IdP.SSOService: Sending back AuthnResponse to ' . $spentityid); - - $attributes = $session->getAttributes(); - - if (!isset($authProcState)) { - - $idpap = $adfsconfig->getValue('authproc'); - if ($idpap) $idpap = array('authproc' => $idpap); else $idpap = array(); - $idpap['entityid'] = $idpentityid; - - $spap = $spmetadata->getValue('authproc'); - if ($spap) $spap = array('authproc' => $spap); else $spap = array(); - $spap['entityid'] = $spentityid; - - $pc = new SimpleSAML_Auth_ProcessingChain($idpap, $spap, 'idp'); - - $authProcState = array( - 'core:adfs-idp:requestcache' => $requestcache, - 'ReturnURL' => SimpleSAML_Utilities::selfURLNoQuery(), - 'Attributes' => $attributes, - 'Destination' => $spap, - 'Source' => $idpap, - 'isPassive' => false, - ); - - $previousSSOTime = $session->getData('adfs-idp-ssotime', $spentityid); - if ($previousSSOTime !== NULL) { - $authProcState['PreviousSSOTimestamp'] = $previousSSOTime; - } - - try { - $pc->processState($authProcState); - } catch (SimpleSAML_Error_NoPassive $e) { - SimpleSAML_Utilities::fatalError($session->getTrackID(), 'GENERATEAUTHNRESPONSE', $exception); - } - - $requestcache['AuthProcState'] = $authProcState; - } - - $attributes = $authProcState['Attributes']; - - $session->setData('adfs-idp-ssotime', $spentityid, time(), - SimpleSAML_Session::DATA_TIMEOUT_LOGOUT); - - $requestID = NULL; $relayState = NULL; - if (array_key_exists('RequestID', $requestcache)) $requestID = $requestcache['RequestID']; - if (array_key_exists('RelayState', $requestcache)) $relayState = $requestcache['RelayState']; - - $nameid = $session->getNameID(); - $nameid = $nameid['Value']; - - $nameidattribute = $spmetadata->getValue('simplesaml.nameidattribute'); - if (isset($nameidattribute)) { - if (!array_key_exists($nameidattribute, $attributes)) { - throw new Exception('simplesaml.nameidattribute does not exist in resulting attribute set'); - } - $nameid = $attributes[$nameidattribute][0]; - } - - $response = ADFS_GenerateResponse($idpentityid, $spentityid, $nameid, $attributes); - $wresult = ADFS_SignResponse($response, $config->getPathValue('certdir', 'cert/') . $adfsconfig->getValue('key'), $config->getPathValue('certdir', 'cert/') . $adfsconfig->getValue('cert')); - - ADFS_PostResponse($spmetadata->getValue('prp'), $wresult, $relayState); - - } catch(Exception $exception) { - SimpleSAML_Utilities::fatalError($session->getTrackID(), 'GENERATEAUTHNRESPONSE', $exception); + if ($_GET['wa'] === 'wsignout1.0') { + sspmod_adfs_IdP_ADFS::receiveLogoutMessage($idp); + } else if ($_GET['wa'] === 'wsignin1.0') { + sspmod_adfs_IdP_ADFS::receiveAuthnRequest($idp); } - + assert('FALSE'); +} elseif(isset($_GET['assocId'])) { + // logout response from ADFS SP + $assocId = $_GET['assocId']; /* Association ID of the SP that sent the logout response. */ + $relayState = $_GET['relayState']; /* Data that was sent in the logout request to the SP. Can be null. */ + $logoutError = NULL; /* NULL on success, or an instance of a SimpleSAML_Error_Exception on failure. */ + $idp->handleLogoutResponse($assocId, $relayState, $logoutError); } ?>