From fc08c1ea5c67dfb27661a8d8e0edf1aa6ee6b505 Mon Sep 17 00:00:00 2001 From: Olav Morken <olav.morken@uninett.no> Date: Fri, 13 Mar 2009 08:15:50 +0000 Subject: [PATCH] Shib13: Clean up authentication response handling. git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@1409 44740490-163a-0410-bde0-09ae8108e29a --- lib/SimpleSAML/Bindings/Shib13/HTTPPost.php | 155 +++++------------- lib/SimpleSAML/XML/Shib13/AuthnResponse.php | 122 +++++++------- www/shib13/idp/SSOService.php | 169 +++++++++----------- 3 files changed, 171 insertions(+), 275 deletions(-) diff --git a/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php b/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php index ee8dc5f18..8b6a14e26 100644 --- a/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php +++ b/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php @@ -16,90 +16,35 @@ class SimpleSAML_Bindings_Shib13_HTTPPost { $this->configuration = $configuration; $this->metadata = $metadatastore; } - - - public function sendResponseUnsigned($response, $idpentityid, $spentityid, $relayState = null, $endpoint = 'AssertionConsumerService') { - SimpleSAML_Utilities::validateXMLDocument($response, 'saml11'); - - $idpmd = $this->metadata->getMetaData($idpentityid, 'saml20-idp-hosted'); - $spmd = $this->metadata->getMetaData($spentityid, 'saml20-sp-remote'); - - $destination = $spmd[$endpoint]; - - echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> - <head> - <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <title>Send SAML 2.0 Authentication Response</title> - </head> - <body> - <h1>Send SAML 2.0 Authentication Response</h1> - - <form style="border: 1px solid #777; margin: 2em; padding: 2em" method="post" action="' . $destination . '"> - <input type="hidden" name="SAMLResponse" value="' . base64_encode($response) . '" /> - <input type="hidden" name="TARGET" value="' . $relayState. '"> - <input type="submit" value="Submit the SAML 1.1 Response" /> - </form> - - <ul> - <li>From IdP: <tt>' . $idpentityid . '</tt></li> - <li>To SP: <tt>' . $spentityid . '</tt></li> - <li>SP Assertion Consumer Service URL: <tt>' . $destination . '</tt></li> - <li>RelayState: <tt>' . $relayState . '</tt></li> - </ul> - - <p>SAML Message: <pre>' . htmlentities($response) . '</pre> - - - </body> - </html>'; - } - /** * Send an authenticationResponse using HTTP-POST. * - * @param $idpmetaindex The metaindex of the IdP to send from. + * @param string $response The response which should be sent. + * @param array $idpmd The metadata of the IdP which is sending the response. + * @param array $spmd The metadata of the SP which is receiving the response. + * @param string|NULL $relayState The relaystate for the SP. + * @param string $shire The shire which should receive the response. */ - public function sendResponse($response, $idpmetaindex, $spentityid, $relayState = null, $claimedacs = null) { + public function sendResponse($response, $idpmd, $spmd, $relayState, $shire) { SimpleSAML_Utilities::validateXMLDocument($response, 'saml11'); - $idpmd = $this->metadata->getMetaData($idpmetaindex, 'shib13-idp-hosted'); - $spmd = $this->metadata->getMetaData($spentityid, 'shib13-sp-remote'); - - $destination = $spmd['AssertionConsumerService']; - - if(!isset($destination) or $destination == '') { - throw new Exception('Could not find AssertionConsumerService for SP entity ID [' . $spentityid. ']. ' . - 'Claimed ACS is: ' . (isset($claimedacs) ? $claimedacs : 'N/A')); - } - - if(strpos($claimedacs, $destination) === 0) { - $destination = $claimedacs; - } else { - throw new Exception('Claimed ACS (shire) and ACS in SP Metadata do not match. [' . $claimedacs. '] [' . $destination . ']'); - } - $privatekey = SimpleSAML_Utilities::loadPrivateKey($idpmd, TRUE); $publickey = SimpleSAML_Utilities::loadPublicKey($idpmd, TRUE); $responsedom = new DOMDocument(); $responsedom->loadXML(str_replace ("\r", "", $response)); - + $responseroot = $responsedom->getElementsByTagName('Response')->item(0); - $firstassertionroot = $responsedom->getElementsByTagName('Assertion')->item(0); - - - + /* Determine what we should sign - either the Response element or the Assertion. The default * is to sign the Assertion, but that can be overridden by the 'signresponse' option in the * SP metadata or 'saml20.signresponse' in the global configuration. */ $signResponse = FALSE; - if(array_key_exists('signresponse', $spmd) && $spmd['signresponse'] !== NULL) { + if (array_key_exists('signresponse', $spmd) && $spmd['signresponse'] !== NULL) { $signResponse = $spmd['signresponse']; if(!is_bool($signResponse)) { throw new Exception('Expected the \'signresponse\' option in the metadata of the' . @@ -108,103 +53,85 @@ class SimpleSAML_Bindings_Shib13_HTTPPost { } else { $signResponse = $this->configuration->getBoolean('shib13.signresponse', TRUE); } - + /* Check if we have an assertion to sign. Force to sign the response if not. */ - if($firstassertionroot === NULL) { + if ($firstassertionroot === NULL) { $signResponse = TRUE; } - - + $signer = new SimpleSAML_XML_Signer(array( 'privatekey_array' => $privatekey, 'publickey_array' => $publickey, 'id' => ($signResponse ? 'ResponseID' : 'AssertionID') , )); - - if(array_key_exists('certificatechain', $idpmd)) { + if (array_key_exists('certificatechain', $idpmd)) { $signer->addCertificate($idpmd['certificatechain']); } - - - if($signResponse) { - /* Sign the response - this must be done after encrypting the assertion. */ + if ($signResponse) { + /* Sign the response - this must be done after encrypting the assertion. */ /* We insert the signature before the saml2p:Status element. */ $statusElements = SimpleSAML_Utilities::getDOMChildren($responseroot, 'Status', '@saml1p'); assert('count($statusElements) === 1'); - $signer->sign($responseroot, $responseroot, $statusElements[0]); - + } else { /* Sign the assertion */ - $signer->sign($firstassertionroot, $firstassertionroot); } - - $response = $responsedom->saveXML(); - - - # openssl genrsa -des3 -out server.key 1024 - # openssl rsa -in server.key -out server.pem - # openssl req -new -key server.key -out server.csr - # openssl x509 -req -days 60 -in server.csr -signkey server.key -out server.crt - + if ($this->configuration->getValue('debug')) { - $p = new SimpleSAML_XHTML_Template($this->configuration, 'post-debug.php'); - $p->data['header'] = 'SAML (Shibboleth 1.3) Response Debug-mode'; $p->data['RelayStateName'] = 'TARGET'; $p->data['RelayState'] = $relayState; - $p->data['destination'] = $destination; + $p->data['destination'] = $shire; $p->data['response'] = str_replace("\n", "", base64_encode($response)); $p->data['responseHTML'] = htmlspecialchars(SimpleSAML_Utilities::formatXMLString($response)); - $p->show(); - } else { - $p = new SimpleSAML_XHTML_Template($this->configuration, 'post.php'); - $p->data['RelayStateName'] = 'TARGET'; $p->data['RelayState'] = $relayState; - $p->data['destination'] = $destination; + $p->data['destination'] = $shire; $p->data['response'] = base64_encode($response); - $p->show(); - - } - - + } - + + + /** + * Decode a received response. + * + * @param array $post POST data received. + * @return SimpleSAML_XML_Shib13_AuthnResponse Response. + */ public function decodeResponse($post) { - $rawResponse = $post["SAMLResponse"]; - $relaystate = $post["TARGET"]; - - $samlResponseXML = base64_decode( $rawResponse ); + assert('is_array($post)'); + + if (!array_key_exists('SAMLResponse', $post)) { + throw new Exception('Missing required SAMLResponse parameter.'); + } + $rawResponse = $post['SAMLResponse']; + $samlResponseXML = base64_decode($rawResponse); SimpleSAML_Utilities::validateXMLDocument($samlResponseXML, 'saml11'); - + $samlResponse = new SimpleSAML_XML_Shib13_AuthnResponse($this->configuration, $this->metadata); - $samlResponse->setXML($samlResponseXML); - - if (isset($relaystate)) { - $samlResponse->setRelayState($relaystate); + + if (array_key_exists('TARGET', $post)) { + $samlResponse->setRelayState($post['TARGET']); } - - return $samlResponse; - - } + return $samlResponse; + } - } ?> \ No newline at end of file diff --git a/lib/SimpleSAML/XML/Shib13/AuthnResponse.php b/lib/SimpleSAML/XML/Shib13/AuthnResponse.php index adf815f7b..a7ad3cd1e 100644 --- a/lib/SimpleSAML/XML/Shib13/AuthnResponse.php +++ b/lib/SimpleSAML/XML/Shib13/AuthnResponse.php @@ -235,22 +235,29 @@ class SimpleSAML_XML_Shib13_AuthnResponse extends SimpleSAML_XML_AuthnResponse { return $nameID; } - - // Not updated for response. from request. - public function generate($idpentityid, $spentityid, $inresponseto, $nameid, $attributes) { - - //echo 'idp:' . $idpentityid . ' sp:' . $spentityid .' inresponseto:' . $inresponseto . ' namid:' . $nameid; - - $idpmd = $this->metadata->getMetaData($idpentityid, 'shib13-idp-hosted'); - $spmd = $this->metadata->getMetaData($spentityid, 'shib13-sp-remote'); - - if (array_key_exists('scopedattributes', $spmd)) { - $scopedAttributes = $spmd['scopedattributes']; - $scopedAttributesSource = 'the shib13-sp-remote sp \'' . $spentityid . '\''; - } elseif (array_key_exists('scopedattributes', $idpmd)) { - $scopedAttributes = $idpmd['scopedattributes']; - $scopedAttributesSource = 'the shib13-idp-hosted idp \'' . $idpentityid . '\''; + + /** + * Build a authentication response. + * + * @param array $idp Metadata for the IdP the response is sent from. + * @param array $sp Metadata for the SP the response is sent to. + * @param string $shire The endpoint on the SP the response is sent to. + * @param array|NULL $attributes The attributes which should be included in the response. + * @return string The response. + */ + public function generate($idp, $sp, $shire, $attributes) { + assert('is_array($idp)'); + assert('is_array($sp)'); + assert('is_string($shire)'); + assert('$attributes === NULL || is_array($attributes)'); + + if (array_key_exists('scopedattributes', $sp)) { + $scopedAttributes = $sp['scopedattributes']; + $scopedAttributesSource = 'the shib13-sp-remote sp \'' . $sp['entityid'] . '\''; + } elseif (array_key_exists('scopedattributes', $idp)) { + $scopedAttributes = $idp['scopedattributes']; + $scopedAttributesSource = 'the shib13-idp-hosted idp \'' . $idp['entityid'] . '\''; } else { $scopedAttributes = array(); } @@ -265,47 +272,45 @@ class SimpleSAML_XML_Shib13_AuthnResponse extends SimpleSAML_XML_AuthnResponse { } } - $id = SimpleSAML_Utilities::generateID(); $issueInstant = SimpleSAML_Utilities::generateTimestamp(); $assertionExpire = SimpleSAML_Utilities::generateTimestamp(time() + 60 * 5);# 5 minutes - $assertionid = SimpleSAML_Utilities::generateID(); - - - if (is_null($nameid)) { - $nameid = SimpleSAML_Utilities::generateID(); - } - $issuer = $idpentityid; + $audience = isset($sp['audience']) ? $sp['audience'] : $sp['entityid']; + $base64 = isset($sp['base64attributes']) ? $sp['base64attributes'] : false; + + $namequalifier = isset($sp['NameQualifier']) ? $sp['NameQualifier'] : $sp['entityid']; + $nameid = SimpleSAML_Utilities::generateID(); + $subjectNode = + '<Subject>' . + '<NameIdentifier' . + ' Format="urn:mace:shibboleth:1.0:nameIdentifier"' . + ' NameQualifier="' . htmlspecialchars($namequalifier) . '"' . + '>' . + htmlspecialchars($nameid) . + '</NameIdentifier>' . + '<SubjectConfirmation>' . + '<ConfirmationMethod>' . + 'urn:oasis:names:tc:SAML:1.0:cm:bearer' . + '</ConfirmationMethod>' . + '</SubjectConfirmation>' . + '</Subject>'; - if (!array_key_exists('AssertionConsumerService', $spmd)) throw new Exception('Could not find [AssertionConsumerService] in Shib 1.3 Service Provider remote metadata.'); - - $shire = $spmd['AssertionConsumerService']; - $audience = isset($spmd['audience']) ? $spmd['audience'] : $spentityid; - $base64 = isset($spmd['base64attributes']) ? $spmd['base64attributes'] : false; - - $namequalifier = isset($spmd['NameQualifier']) ? $spmd['NameQualifier'] : $spmd['entityid']; - $encodedattributes = ''; - + if (is_array($attributes)) { - $encodedattributes .= '<AttributeStatement> - <Subject> - <NameIdentifier Format="urn:mace:shibboleth:1.0:nameIdentifier" NameQualifier="' . htmlspecialchars($namequalifier) . '">' . htmlspecialchars($nameid) . '</NameIdentifier> - <SubjectConfirmation><ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</ConfirmationMethod></SubjectConfirmation> - </Subject>'; - + $encodedattributes .= '<AttributeStatement>'; + $encodedattributes .= $subjectNode; + foreach ($attributes AS $name => $value) { $encodedattributes .= $this->enc_attribute($name, $value, $base64, $scopedAttributes); } - + $encodedattributes .= '</AttributeStatement>'; } - - - + /* * The SAML 1.1 response message */ @@ -314,41 +319,30 @@ class SimpleSAML_XML_Shib13_AuthnResponse extends SimpleSAML_XML_AuthnResponse { xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" IssueInstant="' . $issueInstant. '" MajorVersion="1" MinorVersion="1" - Recipient="' . htmlspecialchars($shire) . '" - ' . (isset($idpmd['edugainInResponseTo']) ? 'InResponseTo="' . $idpmd['edugainInResponseTo'] . '"' : '') . ' - ResponseID="' . $id . '"> - <Status> - <StatusCode Value="samlp:Success"> - <StatusCode xmlns:code="urn:geant:edugain:protocol" Value="code:Accepted" /> - </StatusCode> - </Status> + Recipient="' . htmlspecialchars($shire) . '" ResponseID="' . $id . '"> + <Status> + <StatusCode Value="samlp:Success" /> + </Status> <Assertion xmlns="urn:oasis:names:tc:SAML:1.0:assertion" AssertionID="' . $assertionid . '" IssueInstant="' . $issueInstant. '" - Issuer="' . htmlspecialchars($issuer) . '" MajorVersion="1" MinorVersion="1"> + Issuer="' . htmlspecialchars($idp['entityid']) . '" MajorVersion="1" MinorVersion="1"> <Conditions NotBefore="' . $issueInstant. '" NotOnOrAfter="'. $assertionExpire . '"> <AudienceRestrictionCondition> <Audience>' . htmlspecialchars($audience) . '</Audience> </AudienceRestrictionCondition> </Conditions> <AuthenticationStatement AuthenticationInstant="' . $issueInstant. '" - AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:unspecified"> - <Subject> - <NameIdentifier Format="urn:mace:shibboleth:1.0:nameIdentifier" NameQualifier="' . htmlspecialchars($namequalifier) . '">' . htmlspecialchars($nameid) . '</NameIdentifier> - <SubjectConfirmation> - <ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</ConfirmationMethod> - </SubjectConfirmation> - </Subject> + AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:unspecified">' . + $subjectNode . ' </AuthenticationStatement> ' . $encodedattributes . ' </Assertion> </Response>'; - + return $response; } - - /** * Format a shib13 attribute. * @@ -389,10 +383,10 @@ class SimpleSAML_XML_Shib13_AuthnResponse extends SimpleSAML_XML_AuthnResponse { $attr .= '<AttributeValue' . $scopePart . '>' . htmlspecialchars($value) . '</AttributeValue>'; } $attr .= '</Attribute>'; - + return $attr; - } - + } + } ?> \ No newline at end of file diff --git a/www/shib13/idp/SSOService.php b/www/shib13/idp/SSOService.php index 638c43d7d..666ce4c3c 100644 --- a/www/shib13/idp/SSOService.php +++ b/www/shib13/idp/SSOService.php @@ -22,15 +22,13 @@ if (!$config->getValue('enable.shib13-idp', false)) SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NOACCESS'); try { - $idpentityid = $metadata->getMetaDataCurrentEntityID('shib13-idp-hosted', 'entityid'); - $idpmetaindex = $metadata->getMetaDataCurrentEntityID('shib13-idp-hosted', 'metaindex'); $idpmetadata = $metadata->getMetaDataCurrent('shib13-idp-hosted'); } catch (Exception $exception) { SimpleSAML_Utilities::fatalError($session->getTrackID(), 'METADATA', $exception); } /* - * If the shire query parameter is set, we got an incoming Authentication Request + * If the shire query parameter is set, we got an incoming Authentication Request * at this interface. * * In this case, what we should do is to process the request and set the neccessary information @@ -43,7 +41,7 @@ if (isset($_GET['shire'])) { try { $authnrequest = new SimpleSAML_XML_Shib13_AuthnRequest($config, $metadata); $authnrequest->parseGet($_GET); - + $requestid = $authnrequest->getRequestID(); /* @@ -55,9 +53,12 @@ if (isset($_GET['shire'])) { 'shire' => $authnrequest->getShire(), 'RelayState' => $authnrequest->getRelayState(), ); - - SimpleSAML_Logger::info('Shib1.3 - IdP.SSOService: Got incoming Shib authnRequest requestid: '.$requestid); - + + SimpleSAML_Logger::info('Shib1.3 - IdP.SSOService: Got incoming Shib authnRequest requestid: ' . $requestid); + + if (empty($requestcache['Issuer'])) + throw new Exception('Could not retrieve issuer of the AuthNRequest (ProviderID)'); + } catch(Exception $exception) { SimpleSAML_Utilities::fatalError($session->getTrackID(), 'PROCESSAUTHNREQUEST', $exception); } @@ -67,21 +68,21 @@ if (isset($_GET['shire'])) { * If we did not get an incoming Authenticaiton Request, we need a RequestID parameter. * * The RequestID parameter is used to retrieve the information stored in the session object - * related to the request that was received earlier. Usually the request is processed with + * related to the request that was received earlier. Usually the request is processed with * code above, then the user is redirected to some login module, and when successfully authenticated - * the user isredirected back to this endpoint, and then the user will need to have the RequestID + * the user isredirected back to this endpoint, and then the user will need to have the RequestID * parmeter attached. */ } elseif(isset($_GET['RequestID'])) { - + try { $authId = $_GET['RequestID']; $requestcache = $session->getAuthnRequest('shib13', $authId); - + SimpleSAML_Logger::info('Shib1.3 - IdP.SSOService: Got incoming RequestID: '. $authId); - + if (!$requestcache) { throw new Exception('Could not retrieve cached RequestID = ' . $authId); } @@ -89,7 +90,7 @@ if (isset($_GET['shire'])) { } catch(Exception $exception) { SimpleSAML_Utilities::fatalError($session->getTrackID(), 'CACHEAUTHNREQUEST', $exception); } - + } elseif(isset($_REQUEST[SimpleSAML_Auth_ProcessingChain::AUTHPARAM])) { /* Resume from authentication processing chain. */ @@ -101,6 +102,13 @@ if (isset($_GET['shire'])) { SimpleSAML_Utilities::fatalError($session->getTrackID(), 'SSOSERVICEPARAMS'); } +/* Make sure that the issuer is a valid SP. */ +try { + $spmetadata = $metadata->getMetaData($requestcache['Issuer'], 'shib13-sp-remote'); +} catch (Exception $exception) { + SimpleSAML_Utilities::fatalError($session->getTrackID(), 'PROCESSAUTHNREQUEST', $exception); +} + /* Check whether we should authenticate with an AuthSource. Any time the auth-option matches a * valid AuthSource, we assume that this is the case. */ @@ -132,7 +140,7 @@ if (!$session->isAuthenticated($authority) ) { if($authSource) { /* Authenticate with an AuthSource. */ $hints = array( - 'SPMetadata' => $metadata->getMetaData($requestcache['Issuer'], 'shib13-sp-remote'), + 'SPMetadata' => $spmetadata, 'IdPMetadata' => $idpmetadata, ); @@ -146,97 +154,64 @@ if (!$session->isAuthenticated($authority) ) { 'protocol' => 'shib13', )); } - +} + /* * We got an request, and we hav a valid session. Then we send an AuthenticationResponse back to the * service. */ -} else { +try { + $spmetadata = $metadata->getMetaData($requestcache['Issuer'], 'shib13-sp-remote'); - try { - - $spentityid = $requestcache['Issuer']; - $spmetadata = $metadata->getMetaData($spentityid, 'shib13-sp-remote'); - $sp_name = (isset($spmetadata['name']) ? $spmetadata['name'] : $spentityid); - - $attributes = $session->getAttributes(); - - /** - * Make a log entry in the statistics for this SSO login. - - Need to be replaced by a authproc - - $tempattr = $afilter->getAttributes(); - $realmattr = $config->getValue('statistics.realmattr', null); - $realmstr = 'NA'; - if (!empty($realmattr)) { - if (array_key_exists($realmattr, $tempattr) && is_array($tempattr[$realmattr]) ) { - $realmstr = $tempattr[$realmattr][0]; - } else { - SimpleSAML_Logger::warning('Could not get realm attribute to log [' . $realmattr. ']'); - } - } - */ - SimpleSAML_Logger::stats('shib13-idp-SSO ' . $spentityid . ' ' . $idpentityid . ' NA'); - - - /* Authentication processing operations. */ - if (array_key_exists('AuthProcState', $requestcache)) { - /* Processed earlier, saved in requestcache. */ - $authProcState = $requestcache['AuthProcState']; - - } elseif (isset($authProcState)) { - /* Returned from redirect during processing. */ - $requestcache['AuthProcState'] = $authProcState; - - } else { - /* Not processed. */ - $pc = new SimpleSAML_Auth_ProcessingChain($idpmetadata, $spmetadata, 'idp'); - - $authProcState = array( - 'core:shib13-idp:requestcache' => $requestcache, - 'ReturnURL' => SimpleSAML_Utilities::selfURLNoQuery(), - 'Attributes' => $attributes, - 'Destination' => $spmetadata, - 'Source' => $idpmetadata, - ); - - $pc->processState($authProcState); - - $requestcache['AuthProcState'] = $authProcState; + /* Validate the Shire the response should be sent to. */ + $shire = $requestcache['shire']; + if (!array_key_exists('AssertionConsumerService', $spmetadata)) { + throw new Exception('Could not find [AssertionConsumerService] in Shib 1.3 Service Provider remote metadata.'); + } + $foundACS = FALSE; + foreach (SimpleSAML_Utilities::arrayize($spmetadata['AssertionConsumerService']) as $acs) { + if ($acs === $shire) { + SimpleSAML_Logger::info('Shib1.3 - IdP.SSOService: Found AssertionConsumerService: '. $acs); + $foundACS = TRUE; + break; } + } + if (!$foundACS) { + throw new Exception('Invalid AssertionConsumerService for SP ' . + var_export($spmetadata['entityid'], TRUE) . ': ' . var_export($shire, TRUE)); + } - $attributes = $authProcState['Attributes']; - - - - - // Generating a Shibboleth 1.3 Response. - $ar = new SimpleSAML_XML_Shib13_AuthnResponse($config, $metadata); - $authnResponseXML = $ar->generate($idpentityid, $requestcache['Issuer'], - $requestcache['RequestID'], null, $attributes); - - - #echo $authnResponseXML; - #print_r($authnResponseXML); - - //sendResponse($response, $idpentityid, $spentityid, $relayState = null) { - $httppost = new SimpleSAML_Bindings_Shib13_HTTPPost($config, $metadata); - - //echo 'Relaystate[' . $authnrequest->getRelayState() . ']'; - - $issuer = $requestcache['Issuer']; - $shire = $requestcache['shire']; - if ($issuer == null || $issuer == '') - throw new Exception('Could not retrieve issuer of the AuthNRequest (ProviderID)'); - - $httppost->sendResponse($authnResponseXML, $idpmetaindex, $issuer, $requestcache['RelayState'], $shire); - - } catch(Exception $exception) { - SimpleSAML_Utilities::fatalError($session->getTrackID(), 'GENERATEAUTHNRESPONSE', $exception); + $attributes = $session->getAttributes(); + + SimpleSAML_Logger::stats('shib13-idp-SSO ' . $spmetadata['entityid'] . ' ' . $idpmetadata['entiryid'] . ' NA'); + + /* Authentication processing operations. */ + if (!isset($authProcState)) { + /* Not processed. */ + $pc = new SimpleSAML_Auth_ProcessingChain($idpmetadata, $spmetadata, 'idp'); + + $authProcState = array( + 'core:shib13-idp:requestcache' => $requestcache, + 'ReturnURL' => SimpleSAML_Utilities::selfURLNoQuery(), + 'Attributes' => $attributes, + 'Destination' => $spmetadata, + 'Source' => $idpmetadata, + ); + + $pc->processState($authProcState); } - -} + $attributes = $authProcState['Attributes']; + + /* Generate and send response. */ + $ar = new SimpleSAML_XML_Shib13_AuthnResponse($config, $metadata); + $authnResponseXML = $ar->generate($idpmetadata, $spmetadata, $shire, $attributes); + + $httppost = new SimpleSAML_Bindings_Shib13_HTTPPost($config, $metadata); + $httppost->sendResponse($authnResponseXML, $idpmetadata, $spmetadata, $requestcache['RelayState'], $shire); + +} catch(Exception $exception) { + SimpleSAML_Utilities::fatalError($session->getTrackID(), 'GENERATEAUTHNRESPONSE', $exception); +} ?> \ No newline at end of file -- GitLab