/** * Set the assertion. * * @param SAML2_Assertion $assertion The assertion. * @param XMLSecurityKey $key The key we should use to encrypt the assertion. * @throws Exception */ public function setAssertion(SAML2_Assertion $assertion, XMLSecurityKey $key) { $xml = $assertion->toXML(); SAML2_Utils::getContainer()->debugMessage($xml, 'encrypt'); $enc = new XMLSecEnc(); $enc->setNode($xml); $enc->type = XMLSecEnc::Element; switch ($key->type) { case XMLSecurityKey::TRIPLEDES_CBC: case XMLSecurityKey::AES128_CBC: case XMLSecurityKey::AES192_CBC: case XMLSecurityKey::AES256_CBC: $symmetricKey = $key; break; case XMLSecurityKey::RSA_1_5: case XMLSecurityKey::RSA_OAEP_MGF1P: $symmetricKey = new XMLSecurityKey(XMLSecurityKey::AES128_CBC); $symmetricKey->generateSessionKey(); $enc->encryptKey($key, $symmetricKey); break; default: throw new Exception('Unknown key type for encryption: ' . $key->type); } $this->encryptedData = $enc->encryptNode($symmetricKey); }
public function validate(SAML2_Assertion $assertion, SAML2_Assertion_Validation_Result $result) { $notBeforeTimestamp = $assertion->getNotBefore(); if ($notBeforeTimestamp && $notBeforeTimestamp > SAML2_Utilities_Temporal::getTime() + 60) { $result->addError('Received an assertion that is valid in the future. Check clock synchronization on IdP and SP.'); } }
public function validate(SAML2_Assertion $assertion, SAML2_Assertion_Validation_Result $result) { $notValidOnOrAfterTimestamp = $assertion->getNotOnOrAfter(); if ($notValidOnOrAfterTimestamp && $notValidOnOrAfterTimestamp <= SAML2_Utilities_Temporal::getTime() - 60) { $result->addError('Received an assertion that has expired. Check clock synchronization on IdP and SP.'); } }
/** * @param SAML2_AuthnRequest $authnRequest * @param SimpleSAML_Configuration $idpConfig * @param $nameId * @param $issuer * @param array $attributes * @return SAML2_Response */ public function create(SAML2_AuthnRequest $authnRequest, SimpleSAML_Configuration $idpConfig, $nameId, $issuer, array $attributes) { /* $returnAttributes contains the attributes we should return. Send them. */ $assertion = new SAML2_Assertion(); $assertion->setIssuer($issuer); $assertion->setNameId(array('Value' => $nameId, 'Format' => SAML2_Const::NAMEID_UNSPECIFIED)); $assertion->setNotBefore(time()); $assertion->setNotOnOrAfter(time() + 5 * 60); // Valid audiences is not required so disabled for now // $assertion->setValidAudiences(array($authnRequest->getIssuer())); $assertion->setAttributes($attributes); $assertion->setAttributeNameFormat(SAML2_Const::NAMEFORMAT_UNSPECIFIED); $assertion->setAuthnContext(SAML2_Const::AC_PASSWORD); $subjectConfirmation = new SAML2_XML_saml_SubjectConfirmation(); $subjectConfirmation->Method = SAML2_Const::CM_BEARER; $subjectConfirmation->SubjectConfirmationData = new SAML2_XML_saml_SubjectConfirmationData(); $subjectConfirmation->SubjectConfirmationData->NotOnOrAfter = time() + 5 * 60; $subjectConfirmation->SubjectConfirmationData->Recipient = $authnRequest->getAssertionConsumerServiceURL(); $subjectConfirmation->SubjectConfirmationData->InResponseTo = $authnRequest->getId(); $assertion->setSubjectConfirmation(array($subjectConfirmation)); $response = new SAML2_Response(); $response->setRelayState($authnRequest->getRelayState()); $response->setDestination($authnRequest->getAssertionConsumerServiceURL()); $response->setIssuer($issuer); $response->setInResponseTo($authnRequest->getId()); $response->setAssertions(array($assertion)); $this->addSigns($response, $idpConfig); return $response; }
public function validate(SAML2_Assertion $assertion, SAML2_Assertion_Validation_Result $result) { $intendedAudiences = $assertion->getValidAudiences(); if ($intendedAudiences === NULL) { return; } $entityId = $this->serviceProvider->getEntityId(); if (!in_array($entityId, $intendedAudiences)) { $result->addError(sprintf('The configured Service Provider [%s] is not a valid audience for the assertion. Audiences: [%s]', $entityId, implode('], [', $intendedAudiences))); } }
public function setUp() { $this->request = new EngineBlock_Saml2_AuthnRequestAnnotationDecorator(new SAML2_AuthnRequest()); $assertion = new SAML2_Assertion(); $assertion->setAttributes(array()); $response = new SAML2_Response(); $response->setAssertions(array($assertion)); $response = new EngineBlock_Saml2_ResponseAnnotationDecorator($response); $response->setIntendedNameId('urn:collab:person:example.edu:mock1'); $this->response = $response; $this->serviceProvider = new ServiceProvider('http://sp.example.edu'); $this->collabPersonId = 'urn:collab:person:example.edu:mock1'; $this->resolver = new EngineBlock_Test_Saml2_NameIdResolverMock(); }
public function validate($token) { $data = $this->parseToken($token); // validate digest and thumbprint $assertion = new SAML2_Assertion($data['Assertion']); $certificates = $assertion->getCertificates(); $this->validateCertificateThumbprint($certificates[0]); // validate issuer if ($this->validateIssuer) { $this->validateIssuer($assertion->getIssuer()); } // validate audiences if ($this->validateAudiences) { $this->validateAudiences($assertion->getValidAudiences(), $assertion->getNotBefore(), $assertion->getNotOnOrAfter()); } return $this->getClaims($data); }
public function transform(SAML2_Assertion $assertion) { if (!$assertion->isNameIdEncrypted()) { return $assertion; } $decryptionKeys = $this->privateKeyLoader->loadDecryptionKeys($this->identityProvider, $this->serviceProvider); $blacklistedKeys = $this->identityProvider->getBlacklistedAlgorithms(); if (is_null($blacklistedKeys)) { $blacklistedKeys = $this->serviceProvider->getBlacklistedAlgorithms(); } foreach ($decryptionKeys as $index => $key) { try { $assertion->decryptNameId($key, $blacklistedKeys); $this->logger->debug(sprintf('Decrypted assertion NameId with key "#%d"', $index)); } catch (Exception $e) { $this->logger->debug(sprintf('Decrypting assertion NameId with key "#%d" failed, "%s" thrown: "%s"', $index, get_class($e), $e->getMessage())); } } if ($assertion->isNameIdEncrypted()) { throw new SAML2_Assertion_Exception_NotDecryptedException('Could not decrypt the assertion NameId with the configured keys, see the debug log for information'); } return $assertion; }
/** * Decrypt an assertion. * * This function takes in a SAML2_Assertion and decrypts it if it is encrypted. * If it is unencrypted, and encryption is enabled in the metadata, an exception * will be throws. * * @param SimpleSAML_Configuration $srcMetadata The metadata of the sender (IdP). * @param SimpleSAML_Configuration $dstMetadata The metadata of the recipient (SP). * @param SAML2_Assertion|SAML2_EncryptedAssertion $assertion The assertion we are decrypting. * @return SAML2_Assertion The assertion. */ private static function decryptAssertion(SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata, $assertion) { assert('$assertion instanceof SAML2_Assertion || $assertion instanceof SAML2_EncryptedAssertion'); if ($assertion instanceof SAML2_Assertion) { $encryptAssertion = $srcMetadata->getBoolean('assertion.encryption', NULL); if ($encryptAssertion === NULL) { $encryptAssertion = $dstMetadata->getBoolean('assertion.encryption', FALSE); } if ($encryptAssertion) { /* The assertion was unencrypted, but we have encryption enabled. */ throw new Exception('Received unencrypted assertion, but encryption was enabled.'); } return $assertion; } try { $key = self::getDecryptionKey($srcMetadata, $dstMetadata); } catch (Exception $e) { throw new SimpleSAML_Error_Exception('Error decrypting assertion: ' . $e->getMessage()); } return $assertion->getAssertion($key); }
if (!array_key_exists($name, $attributes)) { /* We don't have this attribute. */ unset($returnAttributes[$name]); continue; } if (count($values) === 0) { /* Return all attributes. */ $returnAttributes[$name] = $attributes[$name]; continue; } /* Filter which attribute values we should return. */ $returnAttributes[$name] = array_intersect($values, $attributes[$name]); } } /* $returnAttributes contains the attributes we should return. Send them. */ $assertion = new SAML2_Assertion(); $assertion->setIssuer($idpEntityId); $assertion->setNameId($query->getNameId()); $assertion->setNotBefore(time()); $assertion->setNotOnOrAfter(time() + 5 * 60); $assertion->setValidAudiences(array($spEntityId)); $assertion->setAttributes($returnAttributes); $assertion->setAttributeNameFormat($attributeNameFormat); $sc = new SAML2_XML_saml_SubjectConfirmation(); $sc->Method = SAML2_Const::CM_BEARER; $sc->SubjectConfirmationData = new SAML2_XML_saml_SubjectConfirmationData(); $sc->SubjectConfirmationData->NotOnOrAfter = time() + 5 * 60; $sc->SubjectConfirmationData->Recipient = $endpoint; $sc->SubjectConfirmationData->InResponseTo = $query->getId(); $assertion->setSubjectConfirmation(array($sc)); sspmod_saml_Message::addSign($idpMetadata, $spMetadata, $assertion);
private function buildResponse($returnAttributes) { /* SubjectConfirmation */ $sc = new SAML2_XML_saml_SubjectConfirmation(); $sc->Method = SAML2_Const::CM_BEARER; $sc->SubjectConfirmationData = new SAML2_XML_saml_SubjectConfirmationData(); $sc->SubjectConfirmationData->NotBefore = time(); $sc->SubjectConfirmationData->NotOnOrAfter = time() + $this->config->getInteger('validFor'); $sc->SubjectConfirmationData->InResponseTo = $this->query->getId(); $assertion = new SAML2_Assertion(); $assertion->setSubjectConfirmation(array($sc)); $assertion->setIssuer($this->aaEntityId); $assertion->setNameId($this->query->getNameId()); $assertion->setNotBefore(time()); $assertion->setNotOnOrAfter(time() + $this->config->getInteger('validFor')); $assertion->setValidAudiences(array($this->spEntityId)); $assertion->setAttributes($returnAttributes); $assertion->setAttributeNameFormat($this->attributeNameFormat); if ($this->signAssertion) { sspmod_saml_Message::addSign($this->aaMetadata, $this->spMetadata, $assertion); } /* The Response */ $response = new SAML2_Response(); $response->setRelayState($this->query->getRelayState()); $response->setIssuer($this->aaEntityId); $response->setInResponseTo($this->query->getId()); $response->setAssertions(array($assertion)); if ($this->signResponse) { sspmod_saml_Message::addSign($this->aaMetadata, $this->spMetadata, $response); } return $response; }
if (!array_key_exists($name, $attributes)) { /* We don't have this attribute. */ unset($returnAttributes[$name]); continue; } if (count($values) === 0) { /* Return all attributes. */ $returnAttributes[$name] = $attributes[$name]; continue; } /* Filter which attribute values we should return. */ $returnAttributes[$name] = array_intersect($values, $attributes[$name]); } } /* $returnAttributes contains the attributes we should return. Send them. */ $assertion = new SAML2_Assertion(); $assertion->setDestination($endpoint); $assertion->setIssuer($idpEntityId); $assertion->setNameId($query->getNameId()); $assertion->setNotBefore(time()); $assertion->setNotOnOrAfter(time() + 5 * 60); $assertion->setInResponseTo($query->getId()); $assertion->setValidAudiences(array($spEntityId)); $assertion->setAttributes($returnAttributes); $assertion->setAttributeNameFormat($attributeNameFormat); sspmod_saml2_Message::addSign($idpMetadata, $spMetadata, $assertion); $response = new SAML2_Response(); $response->setRelayState($query->getRelayState()); $response->setDestination($endpoint); $response->setIssuer($idpEntityId); $response->setInResponseTo($query->getId());
/** * @return EngineBlock_Corto_Module_Bindings */ private function mockBindingsModule() { $spRequest = new SAML2_AuthnRequest(); $spRequest->setId('SPREQUEST'); $spRequest->setIssuer('testSp'); $spRequest = new EngineBlock_Saml2_AuthnRequestAnnotationDecorator($spRequest); $ebRequest = new SAML2_AuthnRequest(); $ebRequest->setId('EBREQUEST'); $ebRequest = new EngineBlock_Saml2_AuthnRequestAnnotationDecorator($ebRequest); $dummyLog = new Psr\Log\NullLogger(); $authnRequestRepository = new EngineBlock_Saml2_AuthnRequestSessionRepository($dummyLog); $authnRequestRepository->store($spRequest); $authnRequestRepository->store($ebRequest); $authnRequestRepository->link($ebRequest, $spRequest); $assertion = new SAML2_Assertion(); $assertion->setAttributes(array('urn:org:openconext:corto:internal:sp-entity-id' => array('testSp'), 'urn:mace:dir:attribute-def:cn' => array(null))); $responseFixture = new SAML2_Response(); $responseFixture->setInResponseTo('EBREQUEST'); $responseFixture->setAssertions(array($assertion)); $responseFixture = new EngineBlock_Saml2_ResponseAnnotationDecorator($responseFixture); $responseFixture->setOriginalIssuer('testIdP'); // Mock bindings module /** @var EngineBlock_Corto_Module_Bindings $bindingsModuleMock */ $bindingsModuleMock = Phake::mock('EngineBlock_Corto_Module_Bindings'); Phake::when($bindingsModuleMock)->receiveResponse()->thenReturn($responseFixture); return $bindingsModuleMock; }
private function mockGlobals() { $_POST['ID'] = 'test'; $_POST['consent'] = 'yes'; $assertion = new SAML2_Assertion(); $assertion->setAttributes(array('urn:mace:dir:attribute-def:mail' => '*****@*****.**')); $spRequest = new SAML2_AuthnRequest(); $spRequest->setId('SPREQUEST'); $spRequest->setIssuer('https://sp.example.edu'); $spRequest = new EngineBlock_Saml2_AuthnRequestAnnotationDecorator($spRequest); $ebRequest = new SAML2_AuthnRequest(); $ebRequest->setId('EBREQUEST'); $ebRequest = new EngineBlock_Saml2_AuthnRequestAnnotationDecorator($ebRequest); $dummySessionLog = new Psr\Log\NullLogger(); $authnRequestRepository = new EngineBlock_Saml2_AuthnRequestSessionRepository($dummySessionLog); $authnRequestRepository->store($spRequest); $authnRequestRepository->store($ebRequest); $authnRequestRepository->link($ebRequest, $spRequest); $sspResponse = new SAML2_Response(); $sspResponse->setInResponseTo('EBREQUEST'); $sspResponse->setAssertions(array($assertion)); $_SESSION['consent']['test']['response'] = new EngineBlock_Saml2_ResponseAnnotationDecorator($sspResponse); }
/** * @param SAML2_AuthnRequest|EngineBlock_Saml2_AuthnRequestAnnotationDecorator $request * @param SAML2_Response|EngineBlock_Saml2_ResponseAnnotationDecorator $sourceResponse */ public function createEnhancedResponse(EngineBlock_Saml2_AuthnRequestAnnotationDecorator $request, EngineBlock_Saml2_ResponseAnnotationDecorator $sourceResponse) { $newResponse = $this->_createBaseResponse($request); // We don't support multiple assertions, only use the first one. $sourceAssertions = $sourceResponse->getAssertions(); $sourceAssertion = $sourceAssertions[0]; // Store the Origin response and issuer (from the IdP) $newResponse->setOriginalResponse($sourceResponse->getOriginalResponse() ? $sourceResponse->getOriginalResponse() : $sourceResponse); $newResponse->setOriginalIssuer($sourceResponse->getOriginalIssuer() ? $sourceResponse->getOriginalIssuer() : $newResponse->getOriginalResponse()->getIssuer()); // Copy over the Status (which should be success) $newResponse->setStatus($sourceResponse->getStatus()); // Create a new assertion by us. $newAssertion = new SAML2_Assertion(); $newResponse->setAssertions(array($newAssertion)); $newAssertion->setId($this->getNewId(IdFrame::ID_USAGE_SAML2_ASSERTION)); $newAssertion->setIssueInstant(time()); $newAssertion->setIssuer($newResponse->getIssuer()); // Unless of course we are in 'stealth' / transparent mode, in which case, // pretend to be the Identity Provider. $serviceProvider = $this->getRepository()->fetchServiceProviderByEntityId($request->getIssuer()); $mustProxyTransparently = $request->isTransparent() || $serviceProvider->isTransparentIssuer; if (!$this->isInProcessingMode() && $mustProxyTransparently) { $newResponse->setIssuer($newResponse->getOriginalIssuer()); $newAssertion->setIssuer($newResponse->getOriginalIssuer()); } // Copy over the NameID for now... // (further on in the filters we'll have more info and set this to something better) $sourceNameId = $sourceAssertion->getNameId(); if (!empty($sourceNameId) && !empty($sourceNameId['Value']) && !empty($sourceNameId['Format'])) { $newAssertion->setNameId(array('Value' => $sourceNameId['Value'], 'Format' => $sourceNameId['Format'])); } // Set up the Subject Confirmation element. $subjectConfirmation = new SAML2_XML_saml_SubjectConfirmation(); $subjectConfirmation->Method = SAML2_Const::CM_BEARER; $newAssertion->setSubjectConfirmation(array($subjectConfirmation)); $subjectConfirmationData = new SAML2_XML_saml_SubjectConfirmationData(); $subjectConfirmation->SubjectConfirmationData = $subjectConfirmationData; // Confirm where we are sending it. $acs = $this->getRequestAssertionConsumer($request); $subjectConfirmationData->Recipient = $acs->location; // Confirm that this is in response to their AuthnRequest (unless, you know, it isn't). if (!$request->isUnsolicited()) { /** @var SAML2_AuthnRequest $request */ $subjectConfirmationData->InResponseTo = $request->getId(); } // Note that it is valid for some 5 minutes. $notOnOrAfter = time() + $this->getConfig('NotOnOrAfter', 300); $newAssertion->setNotBefore(time() - 1); if ($sourceAssertion->getSessionNotOnOrAfter()) { $newAssertion->setSessionNotOnOrAfter($sourceAssertion->getSessionNotOnOrAfter()); } $newAssertion->setNotOnOrAfter($notOnOrAfter); $subjectConfirmationData->NotOnOrAfter = $notOnOrAfter; // And only valid for the SP that requested it. $newAssertion->setValidAudiences(array($request->getIssuer())); // Copy over the Authentication information because the IdP did the authentication, not us. $newAssertion->setAuthnInstant($sourceAssertion->getAuthnInstant()); $newAssertion->setSessionIndex($sourceAssertion->getSessionIndex()); $newAssertion->setAuthnContextClassRef($sourceAssertion->getAuthnContextClassRef()); $newAssertion->setAuthnContextDeclRef($sourceAssertion->getAuthnContextDeclRef()); if ($sourceAssertion->getAuthnContextDecl()) { $newAssertion->setAuthnContextDecl($sourceAssertion->getAuthnContextDecl()); } // Copy over the Authenticating Authorities and add the EntityId of the Source Response Issuer. // Note that because EB generates multiple responses, this will likely result in: // "https://engine/../idp/metadata" !== "https://original-idp/../idpmetadata" => true, gets added // "https://engine/../idp/metadata" !== "https://engine/../idp/metadata" => false, does not get added // "https://engine/../idp/metadata" !== "https://engine/../idp/metadata" => false, does not get added // UNLESS the Response is destined for an SP in VO mode, in which case the flow will be: // "https://engine/../idp/metadata" !== "https://original-idp/../idpmetadata" => true, gets added // "https://engine/../idp/metadata" !== "https://engine/../idp/metadata" => false, does not get added // "https://engine/../idp/metadata/vo:void" !== "https://engine/../idp/metadata" => TRUE, gets added! // This is a 'bug'/'feature' that we're keeping in for BWC reasons. $authenticatingAuthorities = $sourceAssertion->getAuthenticatingAuthority(); if ($this->getUrl('idpMetadataService') !== $sourceResponse->getIssuer()) { $authenticatingAuthorities[] = $sourceResponse->getIssuer(); } $newAssertion->setAuthenticatingAuthority($authenticatingAuthorities); // Copy over the attributes $newAssertion->setAttributes($sourceAssertion->getAttributes()); $newAssertion->setAttributeNameFormat(SAML2_Const::NAMEFORMAT_URI); return $newResponse; }
/** * Decrypt an assertion. * * This function takes in a SAML2_Assertion and decrypts it if it is encrypted. * If it is unencrypted, and encryption is enabled in the metadata, an exception * will be throws. * * @param SimpleSAML_Configuration $srcMetadata The metadata of the sender (IdP). * @param SimpleSAML_Configuration $dstMetadata The metadata of the recipient (SP). * @param SAML2_Assertion|SAML2_EncryptedAssertion $assertion The assertion we are decrypting. * @return SAML2_Assertion The assertion. */ private static function decryptAssertion(SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata, $assertion) { assert('$assertion instanceof SAML2_Assertion || $assertion instanceof SAML2_EncryptedAssertion'); if ($assertion instanceof SAML2_Assertion) { $encryptAssertion = $srcMetadata->getBoolean('assertion.encryption', NULL); if ($encryptAssertion === NULL) { $encryptAssertion = $dstMetadata->getBoolean('assertion.encryption', FALSE); } if ($encryptAssertion) { /* The assertion was unencrypted, but we have encryption enabled. */ throw new Exception('Received unencrypted assertion, but encryption was enabled.'); } return $assertion; } try { $keys = self::getDecryptionKeys($srcMetadata, $dstMetadata); } catch (Exception $e) { throw new SimpleSAML_Error_Exception('Error decrypting assertion: ' . $e->getMessage()); } $blacklist = self::getBlacklistedAlgorithms($srcMetadata, $dstMetadata); $lastException = NULL; foreach ($keys as $i => $key) { try { $ret = $assertion->getAssertion($key, $blacklist); SimpleSAML_Logger::debug('Decryption with key #' . $i . ' succeeded.'); return $ret; } catch (Exception $e) { SimpleSAML_Logger::debug('Decryption with key #' . $i . ' failed with exception: ' . $e->getMessage()); $lastException = $e; } } throw $lastException; }
/** * Tests that AuthnContextDeclRef is not mistaken for AuthnContextClassRef. * * This tests against reintroduction of removed behavior. */ public function testNoAuthnContextDeclRefFallback() { $authnContextDeclRef = 'relative/url/to/authcontext.xml'; // Unmarshall an assertion $document = SAML2_DOMDocumentFactory::fromString(<<<XML <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="_593e33ddf86449ce4d4c22b60ac48e067d98a0b2bf" Version="2.0" IssueInstant="2010-03-05T13:34:28Z" > <saml:Issuer>testIssuer</saml:Issuer> <saml:AuthnStatement AuthnInstant="2010-03-05T13:34:28Z"> <saml:AuthnContext> <saml:AuthnContextDeclRef>{$authnContextDeclRef}</saml:AuthnContextDeclRef> </saml:AuthnContext> </saml:AuthnStatement> </saml:Assertion> XML ); $assertion = new \SAML2_Assertion($document->firstChild); $this->assertEmpty($assertion->getAuthnContextClassRef()); $this->assertEquals($authnContextDeclRef, $assertion->getAuthnContextDeclRef()); }
public function testHasEncryptedAttributes() { $document = new DOMDocument(); $document->loadXML(<<<XML <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0" ID="_93af655219464fb403b34436cfb0c5cb1d9a5502" IssueInstant="1970-01-01T01:33:31Z"> <saml:Issuer>Provider</saml:Issuer> <saml:Subject> <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">s00000000:123456789</saml:NameID> <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <saml:SubjectConfirmationData NotOnOrAfter="2011-08-31T08:51:05Z" Recipient="https://sp.example.com/assertion_consumer" InResponseTo="_13603a6565a69297e9809175b052d115965121c8" /> </saml:SubjectConfirmation> </saml:Subject> <saml:Conditions NotOnOrAfter="2011-08-31T08:51:05Z" NotBefore="2011-08-31T08:51:05Z"> <saml:AudienceRestriction> <saml:Audience>ServiceProvider</saml:Audience> </saml:AudienceRestriction> </saml:Conditions> <saml:AuthnStatement AuthnInstant="2011-08-31T08:51:05Z" SessionIndex="_93af655219464fb403b34436cfb0c5cb1d9a5502"> <saml:AuthnContext> <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef> </saml:AuthnContext> <saml:SubjectLocality Address="127.0.0.1"/> </saml:AuthnStatement> <saml:AttributeStatement> <saml:Attribute Name="urn:ServiceID"> <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">1</saml:AttributeValue> </saml:Attribute> <saml:Attribute Name="urn:EntityConcernedID"> <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">1</saml:AttributeValue> </saml:Attribute> <saml:Attribute Name="urn:EntityConcernedSubID"> <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">1</saml:AttributeValue> </saml:Attribute> <saml:EncryptedAttribute xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Type="http://www.w3.org/2001/04/xmlenc#Element" Id="_F39625AF68B4FC078CC7582D28D05D9C"> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <xenc:EncryptedKey> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/> <ds:KeyInfo> <ds:KeyName>62355fbd1f624503c5c9677402ecca00ef1f6277</ds:KeyName> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue>K0mBLxfLziKVUKEAOYe7D6uVSCPy8vyWVh3RecnPES+8QkAhOuRSuE/LQpFr0huI/iCEy9pde1QgjYDLtjHcujKi2xGqW6jkXW/EuKomqWPPA2xYs1fpB1su4aXUOQB6OJ70/oDcOsy834ghFaBWilE8fqyDBUBvW+2IvaMUZabwN/s9mVkWzM3r30tlkhLK7iOrbGAldIHwFU5z7PPR6RO3Y3fIxjHU40OnLsJc3xIqdLH3fXpC0kgi5UspLdq14e5OoXjLoPG3BO3zwOAIJ8XNBWY5uQof6KrKbcvtZSY0fMvPYhYfNjtRFy8y49ovL9fwjCRTDlT5+aHqsCTBrw==</xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedKey> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue>ZzCu6axGgAYZHVf77NX8apZKB/GJDeuV6bFByBS0AIgiXkvDUAmLCpabTAWBM+yz19olA6rryuOfr82ev2bzPNURvm4SYxahvuL4Pibn5wJky0Bl54VqmcU+Aqj0dAvOgqG1y3X4wO9n9bRsTv6921m0eqRAFph8kK8L9hirK1BxYBYj2RyFCoFDPxVZ5wyra3q4qmE4/ELQpFP6mfU8LXb0uoWJUjGUelS2Aa7bZis8zEpwov4CwtlNjltQih4mv7ttCAfYqcQIFzBTB+DAa0+XggxCLcdB3+mQiRcECBfwHHJ7gRmnuBEgeWT3CGKa3Nb7GMXOfuxFKF5pIehWgo3kdNQLalor8RVW6I8P/I8fQ33Fe+NsHVnJ3zwSA//a</xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData> </saml:EncryptedAttribute> </saml:AttributeStatement> </saml:Assertion> XML ); $assertion = new \SAML2_Assertion($document->firstChild); $this->assertTrue($assertion->hasEncryptedAttributes()); }