/** * Constructs the AuthnRequest object. * * @param OneLogin_Saml2_Settings $settings Settings */ public function __construct(OneLogin_Saml2_Settings $settings) { $this->_settings = $settings; $spData = $this->_settings->getSPData(); $idpData = $this->_settings->getIdPData(); $security = $this->_settings->getSecurityData(); $id = OneLogin_Saml2_Utils::generateUniqueID(); $issueInstant = OneLogin_Saml2_Utils::parseTime2SAML(time()); $nameIDPolicyFormat = $spData['NameIDFormat']; if (isset($security['wantNameIdEncrypted']) && $security['wantNameIdEncrypted']) { $nameIDPolicyFormat = OneLogin_Saml2_Constants::NAMEID_ENCRYPTED; } $providerNameStr = ''; $organizationData = $settings->getOrganization(); if (!empty($organizationData)) { $langs = array_keys($organizationData); if (in_array('en-US', $langs)) { $lang = 'en-US'; } else { $lang = $langs[0]; } if (isset($organizationData[$lang]['displayname']) && !empty($organizationData[$lang]['displayname'])) { $providerNameStr = <<<PROVIDERNAME ProviderName="{$organizationData[$lang]['displayname']}" PROVIDERNAME; } } $request = <<<AUTHNREQUEST <samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="{$id}" Version="2.0" {$providerNameStr} IssueInstant="{$issueInstant}" Destination="{$idpData['singleSignOnService']['url']}" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="{$spData['assertionConsumerService']['url']}"> <saml:Issuer>{$spData['entityId']}</saml:Issuer> <samlp:NameIDPolicy Format="{$nameIDPolicyFormat}" AllowCreate="true" /> AUTHNREQUEST; if (!isset($security['allowedAuthContexts'])) { $security['allowedAuthContexts'] = array('urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport'); } if ($security['allowedAuthContexts'] && is_array($security['allowedAuthContexts'])) { $request .= '<samlp:RequestedAuthnContext Comparison="exact">' . "\n"; foreach ($security['allowedAuthContexts'] as $authCtx) { $request .= '<saml:AuthnContextClassRef>' . $authCtx . "</saml:AuthnContextClassRef>\n"; } $request .= '</samlp:RequestedAuthnContext> ' . "\n"; } $request .= '</samlp:AuthnRequest>'; $this->_id = $id; $this->_authnRequest = $request; }
/** * Returns the metadata of this Service Provider in xml. * @return string Metadata in xml * @throws \Exception * @throws \OneLogin_Saml2_Error */ public function getMetadata() { $oneLoginSetting = new \OneLogin_Saml2_Settings($this->config, true); $metadata = $oneLoginSetting->getSPMetadata(); $errors = $oneLoginSetting->validateMetadata($metadata); if (!empty($errors)) { throw new \Exception('Invalid Metadata Service Provider'); } return $metadata; }
/** * Decrypts the Assertion (DOMDocument) * * @param string $dom DomDocument * * @throws Exception * @return DOMDocument Decrypted Assertion */ private function _decryptAssertion($dom) { $pem = $this->_settings->getSPkey(); if (empty($pem)) { throw new Exception("No private key available, check settings"); } $objenc = new XMLSecEnc(); $encData = $objenc->locateEncryptedData($dom); if (!$encData) { throw new Exception("Cannot locate encrypted assertion"); } $objenc->setNode($encData); $objenc->type = $encData->getAttribute("Type"); if (!($objKey = $objenc->locateKey())) { throw new Exception("Unknown algorithm"); } $key = null; if ($objKeyInfo = $objenc->locateKeyInfo($objKey)) { if ($objKeyInfo->isEncrypted) { $objencKey = $objKeyInfo->encryptedCtx; $objKeyInfo->loadKey($pem, false, false); $key = $objencKey->decryptKey($objKeyInfo); } } if (empty($objKey->key)) { $objKey->loadKey($key); } $decrypt = $objenc->decryptNode($objKey, true); if ($decrypt instanceof DOMDocument) { return $decrypt; } else { return $decrypt->ownerDocument; } }
/** * Generates the Signature for a SAML Response * * @param string $samlResponse The SAML Response * @param string $relayState The RelayState * @param string $signAlgorithm Signature algorithm method * * @return string A base64 encoded signature * * @throws Exception * @throws OneLogin_Saml2_Error */ public function buildResponseSignature($samlResponse, $relayState, $signAlgorithm = XMLSecurityKey::RSA_SHA1) { if (!$this->_settings->checkSPCerts()) { throw new OneLogin_Saml2_Error("Trying to sign the SAML Response but can't load the SP certs", OneLogin_Saml2_Error::SP_CERTS_NOT_FOUND); } $key = $this->_settings->getSPkey(); $objKey = new XMLSecurityKey($signAlgorithm, array('type' => 'private')); $objKey->loadKey($key, false); $security = $this->_settings->getSecurityData(); if ($security['lowercaseUrlencoding']) { $msg = 'SAMLResponse=' . rawurlencode($samlResponse); if (isset($relayState)) { $msg .= '&RelayState=' . rawurlencode($relayState); } $msg .= '&SigAlg=' . rawurlencode($signAlgorithm); } else { $msg = 'SAMLResponse=' . urlencode($samlResponse); if (isset($relayState)) { $msg .= '&RelayState=' . urlencode($relayState); } $msg .= '&SigAlg=' . urlencode($signAlgorithm); } $signature = $objKey->signData($msg); return base64_encode($signature); }
/** * Returns a Logout Response object. * * @param bool|null $deflate Whether or not we should 'gzdeflate' the response body before we return it. * * @return string Logout Response deflated and base64 encoded */ public function getResponse($deflate = null) { $subject = $this->_logoutResponse; if (is_null($deflate)) { $deflate = $this->_settings->shouldCompressResponses(); } if ($deflate) { $subject = gzdeflate($this->_logoutResponse); } return base64_encode($subject); }
/** * Returns deflated, base64 encoded, unsigned AuthnRequest. * */ public function getRequest() { $security = $this->_settings->getSecurityData(); if (isset($security['authnRequestsSigned']) && $security['authnRequestsSigned']) { $base64Request = base64_encode($this->_authnRequest); } else { $deflatedRequest = gzdeflate($this->_authnRequest); $base64Request = base64_encode($deflatedRequest); } return $base64Request; }
/** * Returns deflated, base64 encoded, unsigned AuthnRequest. * * @param bool|null $deflate Whether or not we should 'gzdeflate' the request body before we return it. */ public function getRequest($deflate = null) { $subject = $this->_authnRequest; if (is_null($deflate)) { $deflate = $this->_settings->shouldCompressRequests(); } if ($deflate) { $subject = gzdeflate($this->_authnRequest); } $base64Request = base64_encode($subject); return $base64Request; }
/** * Decrypts the Assertion (DOMDocument) * * @param DomNode $dom DomDocument * * @return DOMDocument Decrypted Assertion * * @throws Exception */ protected function _decryptAssertion($dom) { $pem = $this->_settings->getSPkey(); if (empty($pem)) { throw new Exception("No private key available, check settings"); } $objenc = new XMLSecEnc(); $encData = $objenc->locateEncryptedData($dom); if (!$encData) { throw new Exception("Cannot locate encrypted assertion"); } $objenc->setNode($encData); $objenc->type = $encData->getAttribute("Type"); if (!($objKey = $objenc->locateKey())) { throw new Exception("Unknown algorithm"); } $key = null; if ($objKeyInfo = $objenc->locateKeyInfo($objKey)) { if ($objKeyInfo->isEncrypted) { $objencKey = $objKeyInfo->encryptedCtx; $objKeyInfo->loadKey($pem, false, false); $key = $objencKey->decryptKey($objKeyInfo); } else { // symmetric encryption key support $objKeyInfo->loadKey($pem, false, false); } } if (empty($objKey->key)) { $objKey->loadKey($key); } $decrypted = $objenc->decryptNode($objKey, true); if ($decrypted instanceof DOMDocument) { return $decrypted; } else { $encryptedAssertion = $decrypted->parentNode; $container = $encryptedAssertion->parentNode; # Fix possible issue with saml namespace if (!$decrypted->hasAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:saml') && !$decrypted->hasAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:saml2') && !$decrypted->hasAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns') && !$container->hasAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:saml') && !$container->hasAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:saml2')) { if (strpos($encryptedAssertion->tagName, 'saml2:') !== false) { $ns = 'xmlns:saml2'; } else { if (strpos($encryptedAssertion->tagName, 'saml:') != false) { $ns = 'xmlns:saml'; } else { $ns = 'xmlns'; } } $decrypted->setAttributeNS('http://www.w3.org/2000/xmlns/', $ns, OneLogin_Saml2_Constants::NS_SAML); } $container->replaceChild($decrypted, $encryptedAssertion); return $decrypted->ownerDocument; } }
/** * Generates a Logout Response object. * * @param string $inResponseTo InResponseTo value for the Logout Response. */ public function build($inResponseTo) { $spData = $this->_settings->getSPData(); $idpData = $this->_settings->getIdPData(); $id = OneLogin_Saml2_Utils::generateUniqueID(); $issueInstant = OneLogin_Saml2_Utils::parseTime2SAML(time()); $logoutResponse = <<<LOGOUTRESPONSE <samlp:LogoutResponse xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="{$id}" Version="2.0" IssueInstant="{$issueInstant}" Destination="{$idpData['singleLogoutService']['url']}" InResponseTo="{$inResponseTo}" > <saml:Issuer>{$spData['entityId']}</saml:Issuer> <samlp:Status> <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /> </samlp:Status> </samlp:LogoutResponse> LOGOUTRESPONSE; $this->_logoutResponse = $logoutResponse; }
* additional information regarding copyright ownership. * The Apereo Foundation licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ session_start(); require_once '_toolkit_loader.php'; $samlSettings = new OneLogin_Saml2_Settings(); $idpData = $samlSettings->getIdPData(); if (isset($idpData['singleLogoutService']) && isset($idpData['singleLogoutService']['url'])) { $sloUrl = $idpData['singleLogoutService']['url']; } else { throw new Exception("The IdP does not support Single Log Out"); } if (isset($_SESSION['IdPSessionIndex']) && !empty($_SESSION['IdPSessionIndex'])) { $logoutRequest = new OneLogin_Saml2_LogoutRequest($samlSettings, null, $_SESSION['IdPSessionIndex']); } else { $logoutRequest = new OneLogin_Saml2_LogoutRequest($samlSettings); } $samlRequest = $logoutRequest->getRequest(); $parameters = array('SAMLRequest' => $samlRequest); $url = OneLogin_Saml2_Utils::redirect($sloUrl, $parameters, true); header("Location: {$url}");
<?php /** * SAMPLE Code to demonstrate how to handle a SAML assertion response. * * Your IdP will usually want your metadata, you can use this code to generate it once, * or expose it on a URL so your IdP can check it periodically. */ error_reporting(E_ALL); require_once '../_toolkit_loader.php'; header('Content-Type: text/xml'); $samlSettings = new OneLogin_Saml2_Settings(); $sp = $samlSettings->getSPData(); $samlMetadata = OneLogin_Saml2_Metadata::builder($sp); echo $samlMetadata;
/** * Tests the isDebugActive method of the OneLogin_Saml2_Settings * * @covers OneLogin_Saml2_Settings::isDebugActive */ public function testIsDebugActive() { $settingsDir = TEST_ROOT . '/settings/'; include $settingsDir . 'settings1.php'; unset($settingsInfo['debug']); $settings = new OneLogin_Saml2_Settings($settingsInfo); $this->assertFalse($settings->isDebugActive()); $settingsInfo['debug'] = false; $settings2 = new OneLogin_Saml2_Settings($settingsInfo); $this->assertFalse($settings2->isDebugActive()); $settingsInfo['debug'] = true; $settings3 = new OneLogin_Saml2_Settings($settingsInfo); $this->assertTrue($settings3->isDebugActive()); }
/** * Checks if the Logout Request recieved is valid. * * @return boolean If the Logout Request is or not valid */ public function isValid($retrieveParametersFromServer = false) { $this->_error = null; try { $dom = new DOMDocument(); $dom = OneLogin_Saml2_Utils::loadXML($dom, $this->_logoutRequest); $idpData = $this->_settings->getIdPData(); $idPEntityId = $idpData['entityId']; if ($this->_settings->isStrict()) { $security = $this->_settings->getSecurityData(); if ($security['wantXMLValidation']) { $res = OneLogin_Saml2_Utils::validateXML($dom, 'saml-schema-protocol-2.0.xsd', $this->_settings->isDebugActive()); if (!$res instanceof DOMDocument) { throw new Exception("Invalid SAML Logout Request. Not match the saml-schema-protocol-2.0.xsd"); } } $currentURL = OneLogin_Saml2_Utils::getSelfRoutedURLNoQuery(); // Check NotOnOrAfter if ($dom->documentElement->hasAttribute('NotOnOrAfter')) { $na = OneLogin_Saml2_Utils::parseSAML2Time($dom->documentElement->getAttribute('NotOnOrAfter')); if ($na <= time()) { throw new Exception('Timing issues (please check your clock settings)'); } } // Check destination if ($dom->documentElement->hasAttribute('Destination')) { $destination = $dom->documentElement->getAttribute('Destination'); if (!empty($destination)) { if (strpos($destination, $currentURL) === false) { throw new Exception("The LogoutRequest was received at {$currentURL} instead of {$destination}"); } } } $nameId = $this->getNameId($dom, $this->_settings->getSPkey()); // Check issuer $issuer = $this->getIssuer($dom); if (!empty($issuer) && $issuer != $idPEntityId) { throw new Exception("Invalid issuer in the Logout Request"); } if ($security['wantMessagesSigned']) { if (!isset($_GET['Signature'])) { throw new Exception("The Message of the Logout Request is not signed and the SP require it"); } } } if (isset($_GET['Signature'])) { if (!isset($_GET['SigAlg'])) { $signAlg = XMLSecurityKey::RSA_SHA1; } else { $signAlg = $_GET['SigAlg']; } if ($retrieveParametersFromServer) { $signedQuery = 'SAMLRequest=' . OneLogin_Saml2_Utils::extractOriginalQueryParam('SAMLRequest'); if (isset($_GET['RelayState'])) { $signedQuery .= '&RelayState=' . OneLogin_Saml2_Utils::extractOriginalQueryParam('RelayState'); } $signedQuery .= '&SigAlg=' . OneLogin_Saml2_Utils::extractOriginalQueryParam('SigAlg'); } else { $signedQuery = 'SAMLRequest=' . urlencode($_GET['SAMLRequest']); if (isset($_GET['RelayState'])) { $signedQuery .= '&RelayState=' . urlencode($_GET['RelayState']); } $signedQuery .= '&SigAlg=' . urlencode($signAlg); } if (!isset($idpData['x509cert']) || empty($idpData['x509cert'])) { throw new Exception('In order to validate the sign on the Logout Request, the x509cert of the IdP is required'); } $cert = $idpData['x509cert']; $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'public')); $objKey->loadKey($cert, false, true); if ($signAlg != XMLSecurityKey::RSA_SHA1) { try { $objKey = OneLogin_Saml2_Utils::castKey($objKey, $signAlg, 'public'); } catch (Exception $e) { throw new Exception('Invalid signAlg in the recieved Logout Request'); } } if (!$objKey->verifySignature($signedQuery, base64_decode($_GET['Signature']))) { throw new Exception('Signature validation failed. Logout Request rejected'); } } return true; } catch (Exception $e) { $this->_error = $e->getMessage(); $debug = $this->_settings->isDebugActive(); if ($debug) { echo $this->_error; } return false; } }
/** * Constructs the AuthnRequest object. * * @param OneLogin_Saml2_Settings $settings Settings * @param bool $forceAuthn When true the AuthNReuqest will set the ForceAuthn='true' * @param bool $isPassive When true the AuthNReuqest will set the Ispassive='true' */ public function __construct(OneLogin_Saml2_Settings $settings, $forceAuthn = false, $isPassive = false) { $this->_settings = $settings; $spData = $this->_settings->getSPData(); $idpData = $this->_settings->getIdPData(); $security = $this->_settings->getSecurityData(); $id = OneLogin_Saml2_Utils::generateUniqueID(); $issueInstant = OneLogin_Saml2_Utils::parseTime2SAML(time()); $nameIDPolicyFormat = $spData['NameIDFormat']; echo "1@@@@@@@@@@@@<br /> nameIDPolicyFormat: "; print_r($nameIDPolicyFormat); echo "<br /> OneLogin_Saml2_Constants::NAMEID_ENCRYPTED: "; print_r(OneLogin_Saml2_Constants::NAMEID_ENCRYPTED); echo "2@@@@@@@@@@@@<br />"; //$nameIDPolicyFormat = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"; if (isset($security['wantNameIdEncrypted']) && $security['wantNameIdEncrypted']) { $nameIDPolicyFormat = OneLogin_Saml2_Constants::NAMEID_ENCRYPTED; } $providerNameStr = ''; $organizationData = $settings->getOrganization(); if (!empty($organizationData)) { $langs = array_keys($organizationData); if (in_array('en-US', $langs)) { $lang = 'en-US'; } else { $lang = $langs[0]; } if (isset($organizationData[$lang]['displayname']) && !empty($organizationData[$lang]['displayname'])) { $providerNameStr = <<<PROVIDERNAME ProviderName="{$organizationData[$lang]['displayname']}" PROVIDERNAME; } } $forceAuthnStr = ''; if ($forceAuthn) { $forceAuthnStr = <<<FORCEAUTHN ForceAuthn="true" FORCEAUTHN; } $isPassiveStr = ''; if ($isPassive) { $isPassiveStr = <<<ISPASSIVE IsPassive="true" ISPASSIVE; } $requestedAuthnStr = ''; if (isset($security['requestedAuthnContext']) && $security['requestedAuthnContext'] !== false) { if ($security['requestedAuthnContext'] === true) { $requestedAuthnStr = <<<REQUESTEDAUTHN <samlp:RequestedAuthnContext Comparison="exact"> <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef> </samlp:RequestedAuthnContext> REQUESTEDAUTHN; } else { $requestedAuthnStr .= " <samlp:RequestedAuthnContext Comparison=\"exact\">\n"; foreach ($security['requestedAuthnContext'] as $contextValue) { $requestedAuthnStr .= " <saml:AuthnContextClassRef>" . $contextValue . "</saml:AuthnContextClassRef>\n"; } $requestedAuthnStr .= ' </samlp:RequestedAuthnContext>'; } } $request = <<<AUTHNREQUEST <samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="{$id}" Version="2.0" {$providerNameStr}{$forceAuthnStr}{$isPassiveStr} IssueInstant="{$issueInstant}" Destination="{$idpData['singleSignOnService']['url']}" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="{$spData['assertionConsumerService']['url']}"> <saml:Issuer>{$spData['entityId']}</saml:Issuer> <samlp:NameIDPolicy Format="{$nameIDPolicyFormat}" AllowCreate="true" /> {$requestedAuthnStr} </samlp:AuthnRequest> AUTHNREQUEST; $this->_id = $id; $this->_authnRequest = $request; }
/** * Tests the addX509KeyDescriptors method of the OneLogin_Saml2_Metadata * * @covers OneLogin_Saml2_Metadata::addX509KeyDescriptors */ public function testAddX509KeyDescriptors() { $settingsDir = TEST_ROOT . '/settings/'; include $settingsDir . 'settings1.php'; $settings = new OneLogin_Saml2_Settings($settingsInfo); $spData = $settings->getSPData(); $metadata = OneLogin_Saml2_Metadata::builder($spData); $this->assertNotContains('<md:KeyDescriptor use="signing"', $metadata); $this->assertNotContains('<md:KeyDescriptor use="encryption"', $metadata); $certPath = $settings->getCertPath(); $cert = file_get_contents($certPath . 'sp.crt'); $metadataWithDescriptors = OneLogin_Saml2_Metadata::addX509KeyDescriptors($metadata, $cert); $this->assertContains('<md:KeyDescriptor use="signing"', $metadataWithDescriptors); $this->assertContains('<md:KeyDescriptor use="encryption"', $metadataWithDescriptors); try { $signedMetadata2 = OneLogin_Saml2_Metadata::addX509KeyDescriptors('', $cert); $this->assertFalse(true); } catch (Exception $e) { $this->assertContains('Error parsing metadata', $e->getMessage()); } libxml_use_internal_errors(true); $unparsedMetadata = file_get_contents(TEST_ROOT . '/data/metadata/unparsed_metadata.xml'); try { $metadataWithDescriptors = OneLogin_Saml2_Metadata::addX509KeyDescriptors($unparsedMetadata, $cert); $this->assertFalse(true); } catch (Exception $e) { $this->assertContains('Error parsing metadata', $e->getMessage()); } }
/** * Tests the validateSign method of the OneLogin_Saml2_Utils * * @covers OneLogin_Saml2_Utils::validateSign */ public function testValidateSign() { $settingsDir = TEST_ROOT . '/settings/'; include $settingsDir . 'settings1.php'; $settings = new OneLogin_Saml2_Settings($settingsInfo); $idpData = $settings->getIdPData(); $cert = $idpData['x509cert']; $fingerprint = OneLogin_Saml2_Utils::calculateX509Fingerprint($cert); $xmlMetadataSigned = file_get_contents(TEST_ROOT . '/data/metadata/signed_metadata_settings1.xml'); $this->assertTrue(OneLogin_Saml2_Utils::validateSign($xmlMetadataSigned, $cert)); $this->assertTrue(OneLogin_Saml2_Utils::validateSign($xmlMetadataSigned, null, $fingerprint)); $xmlResponseMsgSigned = base64_decode(file_get_contents(TEST_ROOT . '/data/responses/signed_message_response.xml.base64')); $this->assertTrue(OneLogin_Saml2_Utils::validateSign($xmlResponseMsgSigned, $cert)); $this->assertTrue(OneLogin_Saml2_Utils::validateSign($xmlResponseMsgSigned, null, $fingerprint)); $xmlResponseAssertSigned = base64_decode(file_get_contents(TEST_ROOT . '/data/responses/signed_assertion_response.xml.base64')); $this->assertTrue(OneLogin_Saml2_Utils::validateSign($xmlResponseAssertSigned, $cert)); $this->assertTrue(OneLogin_Saml2_Utils::validateSign($xmlResponseAssertSigned, null, $fingerprint)); $xmlResponseDoubleSigned = base64_decode(file_get_contents(TEST_ROOT . '/data/responses/double_signed_response.xml.base64')); $this->assertTrue(OneLogin_Saml2_Utils::validateSign($xmlResponseDoubleSigned, $cert)); $this->assertTrue(OneLogin_Saml2_Utils::validateSign($xmlResponseDoubleSigned, null, $fingerprint)); $dom = new DOMDocument(); $dom->loadXML($xmlResponseMsgSigned); $this->assertTrue(OneLogin_Saml2_Utils::validateSign($dom, $cert)); $dom->firstChild->firstChild->nodeValue = 'https://example.com/other-idp'; try { $this->assertFalse(OneLogin_Saml2_Utils::validateSign($dom, $cert)); $this->assertTrue(false); } catch (Exception $e) { $this->assertContains('Reference validation failed', $e->getMessage()); } $dom2 = new DOMDocument(); $dom2->loadXML($xmlResponseMsgSigned); $assertElem = $dom2->firstChild->firstChild->nextSibling->nextSibling; $this->assertTrue(OneLogin_Saml2_Utils::validateSign($assertElem, $cert)); $dom3 = new DOMDocument(); $dom3->loadXML($xmlResponseMsgSigned); $dom3->firstChild->firstChild->nodeValue = 'https://example.com/other-idp'; $assertElem2 = $dom3->firstChild->firstChild->nextSibling->nextSibling; try { $this->assertTrue(OneLogin_Saml2_Utils::validateSign($assertElem2, $cert)); $this->assertTrue(false); } catch (Exception $e) { $this->assertContains('Reference validation failed', $e->getMessage()); } $invalidFingerprint = 'afe71c34ef740bc87434be13a2263d31271da1f9'; $this->assertFalse(OneLogin_Saml2_Utils::validateSign($xmlMetadataSigned, null, $invalidFingerprint)); $noSigned = base64_decode(file_get_contents(TEST_ROOT . '/data/responses/invalids/no_signature.xml.base64')); try { $this->assertFalse(OneLogin_Saml2_Utils::validateSign($noSigned, $cert)); $this->assertTrue(false); } catch (Exception $e) { $this->assertContains('Cannot locate Signature Node', $e->getMessage()); } $noKey = base64_decode(file_get_contents(TEST_ROOT . '/data/responses/invalids/no_key.xml.base64')); try { $this->assertFalse(OneLogin_Saml2_Utils::validateSign($noKey, $cert)); $this->assertTrue(false); } catch (Exception $e) { $this->assertContains('We have no idea about the key', $e->getMessage()); } }
/** * Tests the isValid method of the OneLogin_Saml2_Response * Case invalid xml * * @covers OneLogin_Saml2_Response::isValid */ public function testIsInValidWrongXML() { $settingsDir = TEST_ROOT . '/settings/'; include $settingsDir . 'settings1.php'; $settingsInfo['security']['wantXMLValidation'] = false; $settings = new OneLogin_Saml2_Settings($settingsInfo); $settings->setStrict(false); $xml = file_get_contents(TEST_ROOT . '/data/responses/invalids/invalid_xml.xml.base64'); $response = new OneLogin_Saml2_Response($settings, $xml); $this->assertTrue($response->isValid()); $settings->setStrict(true); $response2 = new OneLogin_Saml2_Response($settings, $xml); $response2->isValid(); $this->assertNotEquals('Invalid SAML Response. Not match the saml-schema-protocol-2.0.xsd', $response2->getError()); $settingsInfo['security']['wantXMLValidation'] = true; $settings2 = new OneLogin_Saml2_Settings($settingsInfo); $settings2->setStrict(false); $response3 = new OneLogin_Saml2_Response($settings2, $xml); $this->assertTrue($response3->isValid()); $settings2->setStrict(true); $response4 = new OneLogin_Saml2_Response($settings2, $xml); $this->assertFalse($response4->isValid()); $this->assertEquals('Invalid SAML Response. Not match the saml-schema-protocol-2.0.xsd', $response4->getError()); }
<?php /** * SAML Metadata view */ require_once dirname(dirname(__FILE__)) . '/_toolkit_loader.php'; require_once 'settings.php'; try { #$auth = new OneLogin_Saml2_Auth($settingsInfo); #$settings = $auth->getSettings(); // Now we only validate SP settings $settings = new OneLogin_Saml2_Settings($settingsInfo, true); $metadata = $settings->getSPMetadata(); $errors = $settings->validateMetadata($metadata); if (empty($errors)) { header('Content-Type: text/xml'); echo $metadata; } else { throw new OneLogin_Saml2_Error('Invalid SP metadata: ' . implode(', ', $errors), OneLogin_Saml2_Error::METADATA_SP_INVALID); } } catch (Exception $e) { echo $e->getMessage(); }
<?php /** * SAMPLE Code to demonstrate how to initiate a SAML Authorization request * * When the user visits this URL, the browser will be redirected to the SSO * IdP with an authorization request. If successful, it will then be * redirected to the consume URL (specified in settings) with the auth * details. */ session_start(); require_once '../_toolkit_loader.php'; if (!isset($_SESSION['samlUserdata'])) { $settings = new OneLogin_Saml2_Settings(); $authRequest = new OneLogin_Saml2_AuthnRequest($settings); $samlRequest = $authRequest->getRequest(); $parameters = array('SAMLRequest' => $samlRequest); $parameters['RelayState'] = OneLogin_Saml2_Utils::getSelfURLNoQuery(); $idpData = $settings->getIdPData(); $ssoUrl = $idpData['singleSignOnService']['url']; $url = OneLogin_Saml2_Utils::redirect($ssoUrl, $parameters, true); header("Location: {$url}"); } else { if (!empty($_SESSION['samlUserdata'])) { $attributes = $_SESSION['samlUserdata']; echo 'You have the following attributes:<br>'; echo '<table><thead><th>Name</th><th>Values</th></thead><tbody>'; foreach ($attributes as $attributeName => $attributeValues) { echo '<tr><td>' . htmlentities($attributeName) . '</td><td><ul>'; foreach ($attributeValues as $attributeValue) { echo '<li>' . htmlentities($attributeValue) . '</li>';
public function __construct($config) { $settings = array('sp' => array('entityId' => $config['sp']['entity_id'], 'assertionConsumerService' => array('url' => $config['sp']['acs'], 'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'), 'singleLogoutService' => array('url' => $config['sp']['sls'], 'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'), 'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:unspecified')); parent::__construct($settings, true); }