public static function cacheResponse(EngineBlock_Saml2_AuthnRequestAnnotationDecorator $receivedRequest, EngineBlock_Saml2_ResponseAnnotationDecorator $receivedResponse, $type) { if ($type !== self::RESPONSE_CACHE_TYPE_IN) { throw new EngineBlock_Exception('Unknown response type'); } if (!isset($_SESSION['CachedResponses'])) { $_SESSION['CachedResponses'] = array(); } $_SESSION['CachedResponses'][] = array('sp' => $receivedRequest->getIssuer(), 'idp' => $receivedResponse->getIssuer(), 'type' => $type, 'response' => $receivedResponse, 'vo' => $receivedRequest->getVoContext(), 'key' => $receivedRequest->getKeyId()); }
/** * @return EngineBlock_Saml2_AuthnRequestAnnotationDecorator * @throws EngineBlock_Corto_Module_Bindings_UnsupportedBindingException * @throws EngineBlock_Corto_Module_Bindings_VerificationException * @throws EngineBlock_Corto_Module_Bindings_Exception */ public function receiveRequest() { // Detect the current binding from the super globals $sspBinding = SAML2_Binding::getCurrentBinding(); // Receive the request. $sspRequest = $sspBinding->receive(); if (!$sspRequest instanceof SAML2_AuthnRequest) { throw new EngineBlock_Corto_Module_Bindings_UnsupportedBindingException('Unsupported Binding used', EngineBlock_Exception::CODE_NOTICE); } $ebRequest = new EngineBlock_Saml2_AuthnRequestAnnotationDecorator($sspRequest); // Make sure the request from the sp has an Issuer $spEntityId = $ebRequest->getIssuer(); if (!$spEntityId) { throw new EngineBlock_Corto_Module_Bindings_Exception('Missing <saml:Issuer> in message delivered to AssertionConsumerService.'); } // Remember sp for debugging $_SESSION['currentServiceProvider'] = $ebRequest->getIssuer(); // Verify that we know this SP and have metadata for it. $serviceProvider = $this->_verifyKnownMessageIssuer($spEntityId, $ebRequest->getDestination()); if (!$serviceProvider instanceof ServiceProvider) { throw new EngineBlock_Corto_Module_Bindings_Exception("Requesting entity '{$spEntityId}' is not a Service Provider"); } // Load the metadata for this IdP in SimpleSAMLphp style $sspSpMetadata = SimpleSAML_Configuration::loadFromArray($this->mapCortoEntityMetadataToSspEntityMetadata($serviceProvider)); // Determine if we should check the signature of the message $wantRequestsSigned = $serviceProvider->requestsMustBeSigned || $this->_server->getConfig('WantsAuthnRequestsSigned'); // If we should, then check it. if ($wantRequestsSigned) { // Check the Signature on the Request, if there is no signature, or verification fails // throw an exception. $className = $this->_sspmodSamlMessageClassName; if (!$className::checkSign($sspSpMetadata, $ebRequest->getSspMessage())) { throw new EngineBlock_Corto_Module_Bindings_VerificationException('Validation of received messages enabled, but no signature found on message.'); } /** @var EngineBlock_Saml2_AuthnRequestAnnotationDecorator $ebRequest */ $ebRequest->setWasSigned(); } $this->_annotateRequestWithVoContext($ebRequest, $serviceProvider); $this->_annotateRequestWithKeyId($ebRequest); return $ebRequest; }
public static function createFromRequest(EngineBlock_Saml2_AuthnRequestAnnotationDecorator $originalRequest, IdentityProvider $idpMetadata, EngineBlock_Corto_ProxyServer $server) { $nameIdPolicy = array('AllowCreate' => 'true'); /** * Name policy is not required, so it is only set if configured, SAML 2.0 spec * says only following values are allowed: * - urn:oasis:names:tc:SAML:2.0:nameid-format:transient * - urn:oasis:names:tc:SAML:2.0:nameid-format:persistent. * * Note: Some IDP's like those using ADFS2 do not understand those, for these cases the format can be 'configured as empty * or set to an older version. */ if (!empty($idpMetadata->nameIdFormat)) { $nameIdPolicy['Format'] = $idpMetadata->nameIdFormat; } /** @var SAML2_AuthnRequest $originalRequest */ $sspRequest = new SAML2_AuthnRequest(); $sspRequest->setId($server->getNewId(\OpenConext\Component\EngineBlockFixtures\IdFrame::ID_USAGE_SAML2_REQUEST)); $sspRequest->setIssueInstant(time()); $sspRequest->setDestination($idpMetadata->singleSignOnServices[0]->location); $sspRequest->setForceAuthn($originalRequest->getForceAuthn()); $sspRequest->setIsPassive($originalRequest->getIsPassive()); $sspRequest->setAssertionConsumerServiceURL($server->getUrl('assertionConsumerService')); $sspRequest->setProtocolBinding(SAML2_Const::BINDING_HTTP_POST); $sspRequest->setIssuer($server->getUrl('spMetadataService')); $sspRequest->setNameIdPolicy($nameIdPolicy); if (empty($idpMetadata->disableScoping)) { // Copy over the Idps that are allowed to answer this request. $sspRequest->setIDPList($originalRequest->getIDPList()); // Proxy Count $sspRequest->setProxyCount($originalRequest->getProxyCount() ? $originalRequest->getProxyCount() : $server->getConfig('max_proxies', 10)); // Add the SP to the requesterIds $requesterIds = $originalRequest->getRequesterID(); $requesterIds[] = $originalRequest->getIssuer(); // Add the SP as the requester $sspRequest->setRequesterID($requesterIds); } // Use the default binding even if more exist $request = new EngineBlock_Saml2_AuthnRequestAnnotationDecorator($sspRequest); $request->setDeliverByBinding($idpMetadata->singleSignOnServices[0]->binding); return $request; }
protected function _showWayf(EngineBlock_Saml2_AuthnRequestAnnotationDecorator $request, array $candidateIdpEntityIds) { // Post to the 'continueToIdp' service $action = $this->_server->getUrl('continueToIdP'); $serviceProvider = $this->_server->getRepository()->fetchServiceProviderByEntityId($request->getIssuer()); $idpList = $this->_transformIdpsForWAYF($candidateIdpEntityIds, $request->isDebugRequest()); $output = $this->_server->renderTemplate('discover', array('preselectedIdp' => $this->_server->getCookie('selectedIdp'), 'action' => $action, 'ID' => $request->getId(), 'idpList' => $idpList, 'metaDataSP' => $serviceProvider)); $this->_server->sendOutput($output); }
public function sendResponseToRequestIssuer(EngineBlock_Saml2_AuthnRequestAnnotationDecorator $request, EngineBlock_Saml2_ResponseAnnotationDecorator $response) { /** @var SAML2_AuthnRequest $request */ $requestIssuer = $request->getIssuer(); $serviceProvider = $this->getRepository()->fetchServiceProviderByEntityId($requestIssuer); // Detect error responses and send them off without an assertion. /** @var SAML2_Response $response */ $status = $response->getStatus(); if ($status['Code'] !== 'urn:oasis:names:tc:SAML:2.0:status:Success') { $response->setAssertions(array()); $this->getBindingsModule()->send($response, $serviceProvider); return; } $this->filterOutputAssertionAttributes($response, $request); $this->getBindingsModule()->send($response, $serviceProvider); }