function verificar_acceso($datos_iniciales = null) { $auth = $this->instanciar_pedido_onelogin(); if (!is_null(toba::memoria()->get_parametro('acs'))) { //Se verifica la respuesta y se chequea la autenticacion $auth->processResponse(); $this->verificar_errores_onelogin($auth); if (!$auth->isAuthenticated()) { throw new toba_error_autenticacion('No ha sido posible autenticar al usuario'); } $this->set_atributos_usuario($auth->getAttributes()); $id_usuario = $this->recuperar_usuario_toba(); //Recupero usr y verifico existencia en toba, excepcion si no existe try { toba::manejador_sesiones()->login($id_usuario, 'foobar', $datos_iniciales); //La clave no importa porque se autentifica via token } catch (toba_reset_nucleo $e) { if (isset($_POST['RelayState']) && OneLogin_Saml2_Utils::getSelfURL() != $_POST['RelayState']) { $auth->redirectTo($_POST['RelayState']); } else { throw $e; } } return $id_usuario; } else { $this->procesar_logout($auth); //Se hace el redirect hacia el idp $parametros_url = array(); if (isset($this->parametros_url) && is_array($this->parametros_url)) { $parametros_url = $this->parametros_url; } $auth->login($this->generar_url($parametros_url)); } }
/** * Constructor * * @param string $msg Describes the error. * @param integer $code The code error (defined in the error class). * @param array $args Arguments used in the message that describes the error. */ public function __construct($msg, $code = 0, $args = null) { assert('is_string($msg)'); assert('is_int($code)'); $message = OneLogin_Saml2_Utils::t($msg, $args); parent::__construct($message, $code); }
/** * 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; }
public function acsAction(Request $req) { $auth = $this->get('arcanys_sso_auth.saml2'); $auth->processResponse(); $errors = $auth->getErrors(); if (!empty($errors)) { throw new \Exception(implode(', ', $errors)); } if (!$auth->isAuthenticated()) { throw new AccessDeniedHttpException(); } $session = $this->get('session'); $session->getFlashBag()->set('arcanys_sso_auth.user_data', $auth->getAttributes()); $session->getFlashBag()->set('arcanys_sso_auth.name_id', $auth->getNameId()); $session->getFlashBag()->set('arcanys_sso_auth.session_index', $auth->getSessionIndex()); if ($req->request->get('RelayState') && \OneLogin_Saml2_Utils::getSelfURL() != $req->request->get('RelayState')) { // $auth->redirectTo($req->request->get('RelayState')); return $this->redirect($req->request->get('RelayState')); } }
/** * Tests the OneLogin_Saml2_AuthnRequest Constructor. * The creation of a deflated SAML Request * * @covers OneLogin_Saml2_AuthnRequest */ public function testCreateEncSAMLRequest() { $settingsDir = TEST_ROOT . '/settings/'; include $settingsDir . 'settings1.php'; $settingsInfo['organization'] = array('es' => array('name' => 'sp_prueba', 'displayname' => 'SP prueba', 'url' => 'http://sp.example.com')); $settingsInfo['security']['wantNameIdEncrypted'] = true; $settings = new OneLogin_Saml2_Settings($settingsInfo); $authnRequest = new OneLogin_Saml2_AuthnRequest($settings); $parameters = array('SAMLRequest' => $authnRequest->getRequest()); $authUrl = OneLogin_Saml2_Utils::redirect('http://idp.example.com/SSOService.php', $parameters, true); $this->assertRegExp('#^http://idp\\.example\\.com\\/SSOService\\.php\\?SAMLRequest=#', $authUrl); parse_str(parse_url($authUrl, PHP_URL_QUERY), $exploded); // parse_url already urldecode de params so is not required. $payload = $exploded['SAMLRequest']; $decoded = base64_decode($payload); $message = gzinflate($decoded); $this->assertRegExp('#^<samlp:AuthnRequest#', $message); $this->assertRegExp('#AssertionConsumerServiceURL="http://stuff.com/endpoints/endpoints/acs.php">#', $message); $this->assertRegExp('#<saml:Issuer>http://stuff.com/endpoints/metadata.php</saml:Issuer>#', $message); $this->assertRegExp('#Format="urn:oasis:names:tc:SAML:2.0:nameid-format:encrypted"#', $message); $this->assertRegExp('#ProviderName="SP prueba"#', $message); }
/** * Initiates the SLO process. * * @param string $returnTo The target URL the user should be returned to after logout. * @param array $parameters Extra parameters to be added to the GET * @param string $nameId The NameID that will be set in the LogoutRequest. * @param string $sessionIndex The SessionIndex (taken from the SAML Response in the SSO process). */ public function logout($returnTo = null, $parameters = array(), $nameId = null, $sessionIndex = null) { assert('is_array($parameters)'); $sloUrl = $this->getSLOurl(); if (empty($sloUrl)) { throw new OneLogin_Saml2_Error('The IdP does not support Single Log Out', OneLogin_Saml2_Error::SAML_SINGLE_LOGOUT_NOT_SUPPORTED); } if (empty($nameId) && !empty($this->_nameid)) { $nameId = $this->_nameid; } $logoutRequest = new OneLogin_Saml2_LogoutRequest($this->_settings, null, $nameId, $sessionIndex); $samlRequest = $logoutRequest->getRequest(); $parameters['SAMLRequest'] = $samlRequest; if (!empty($returnTo)) { $parameters['RelayState'] = $returnTo; } else { $parameters['RelayState'] = OneLogin_Saml2_Utils::getSelfRoutedURLNoQuery(); } $security = $this->_settings->getSecurityData(); if (isset($security['logoutRequestSigned']) && $security['logoutRequestSigned']) { $signature = $this->buildRequestSignature($samlRequest, $parameters['RelayState'], $security['signatureAlgorithm']); $parameters['SigAlg'] = $security['signatureAlgorithm']; $parameters['Signature'] = $signature; } return $this->redirectTo($sloUrl, $parameters); }
/** * Formats the SP private key. */ public function formatSPKey() { if (isset($this->_sp['privateKey'])) { $this->_sp['privateKey'] = OneLogin_Saml2_Utils::formatPrivateKey($this->_sp['privateKey']); } }
/** * Validates a signature (Message or Assertion). * * @param string|DomDocument $xml The element we should validate * @param string|null $cert The pubic cert * @param string|null $fingerprint The fingerprint of the public cert * @param string|null $fingerprintalg The algorithm used to get the fingerprint */ public static function validateSign($xml, $cert = null, $fingerprint = null, $fingerprintalg = 'sha1') { if ($xml instanceof DOMDocument) { $dom = clone $xml; } else { if ($xml instanceof DOMElement) { $dom = clone $xml->ownerDocument; } else { $dom = new DOMDocument(); $dom = self::loadXML($dom, $xml); } } # Check if Reference URI is empty try { $signatureElems = $dom->getElementsByTagName('Signature'); foreach ($signatureElems as $signatureElem) { $referenceElems = $dom->getElementsByTagName('Reference'); if (count($referenceElems) > 0) { $referenceElem = $referenceElems->item(0); if ($referenceElem->getAttribute('URI') == '') { $referenceElem->setAttribute('URI', '#' . $signatureElem->parentNode->getAttribute('ID')); } } } } catch (Exception $e) { continue; } $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->idKeys = array('ID'); $objDSig = $objXMLSecDSig->locateSignature($dom); if (!$objDSig) { throw new Exception('Cannot locate Signature Node'); } $objKey = $objXMLSecDSig->locateKey(); if (!$objKey) { throw new Exception('We have no idea about the key'); } $objXMLSecDSig->canonicalizeSignedInfo(); try { $retVal = $objXMLSecDSig->validateReference(); } catch (Exception $e) { throw $e; } XMLSecEnc::staticLocateKeyInfo($objKey, $objDSig); if (!empty($cert)) { $objKey->loadKey($cert, false, true); return $objXMLSecDSig->verify($objKey) === 1; } else { $domCert = $objKey->getX509Certificate(); $domCertFingerprint = OneLogin_Saml2_Utils::calculateX509Fingerprint($domCert, $fingerprintalg); if (OneLogin_Saml2_Utils::formatFingerPrint($fingerprint) !== $domCertFingerprint) { return false; } else { $objKey->loadKey($domCert, false, true); return $objXMLSecDSig->verify($objKey) === 1; } } }
* as published by the Free Software Foundation; version 2 * of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ require_once dirname(__FILE__) . '/../../includes/core.inc.php'; include_once dirname(dirname(dirname(__FILE__))) . '/PEAR/php-saml/_toolkit_loader.php'; if (!defined('SAML2_REDIRECT_URI')) { define('SAML2_REDIRECT_URI', OneLogin_Saml2_Utils::getSelfURLhost()); } function send_error($message) { die(<<<EOF <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" \t"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> \t<title>SAML2 Error</title> \t<meta http-equiv="content-type" content="text/html;charset=utf-8" /> \t<link rel="stylesheet" type="text/css" href="/ovd/media/style/webclient.css" /> </head> <body> \t<div id="overlay"> \t\t<div class="shadowBox" id="systemTestError">
/** * SAML 2.0 Auth test endpoint * * FIXME remove termporary saml2 acs endpoint */ public function samlAction() { /* FIXME We'll enable \Scalr::config('scalr.auth_mode') !== 'saml' when it is production ready if (\Scalr::config('scalr.auth_mode') !== 'saml') { $this->response->setHttpResponseCode(404); return; } */ @session_start(); //This is necessary for test container as OneLogin_Saml2_Utils::getSelfHost() method relies on HTTP_HOST / SERVER_PORT $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST']; $auth = $this->getContainer()->saml; $body = ''; if (isset($_GET['sso'])) { $auth->login(); } else { if (isset($_GET['slo'])) { $auth->logout(null, [], isset($_SESSION['samlNameId']) ? $_SESSION['samlNameId'] : null, isset($_SESSION['samlSessionIndex']) ? $_SESSION['samlSessionIndex'] : null); } else { if (isset($_GET['acs'])) { $auth->processResponse(); $errors = $auth->getErrors(); if (!empty($errors)) { $body .= '<p>' . implode(', ', $errors) . '</p>'; } if (!$auth->isAuthenticated()) { $body .= "<p>Not authenticated</p>"; $this->response->body = $body; return; } $_SESSION['samlUserdata'] = $auth->getAttributes(); $_SESSION['samlNameId'] = $auth->getNameId(); $_SESSION['samlSessionIndex'] = $auth->getSessionIndex(); if (isset($_POST['RelayState']) && OneLogin_Saml2_Utils::getSelfURL() != $_POST['RelayState']) { $auth->redirectTo($_POST['RelayState']); return; } } else { if (isset($_GET['sls'])) { $auth->processSLO(); $errors = $auth->getErrors(); if (empty($errors)) { $body .= '<p>Sucessfully logged out</p>'; } else { $body .= '<p>' . implode(', ', $errors) . '</p>'; } } else { if (isset($_GET['metadata'])) { $settings = $auth->getSettings(); // Now we only validate SP settings $metadata = $settings->getSPMetadata(); $errors = $settings->validateMetadata($metadata); if (empty($errors)) { $this->response->setHeader('Content-Type', 'text/xml'); $this->response->body = $metadata; return; } else { throw new OneLogin_Saml2_Error('Invalid SP metadata: ' . implode(', ', $errors), OneLogin_Saml2_Error::METADATA_SP_INVALID); } } } } } } if (isset($_SESSION['samlUserdata'])) { if (!empty($_SESSION['samlUserdata'])) { $attributes = $_SESSION['samlUserdata']; $body .= '<style type="text/css">' . ' th, td { border: 1px solid black; padding: 2px 4px; }' . ' ul { padding: 1px 2px; margin: 0px; }' . ' ul li { list-style-type: none; }' . '</style>'; $body .= 'Scalr requires following attributes:<br>'; $body .= '<table><thead><th>Name</th><th>Values</th></thead><tbody>'; $body .= '<tr><td>Email</td><td><ul><li>' . htmlentities($_SESSION['samlNameId']) . '</li></ul></td></tr>'; $body .= '<tr><td>Groups</td><td><ul><li>' . (!empty($_SESSION['samlUserdata']['Groups']) ? join(', ', array_map('htmlentities', (array) $_SESSION['samlUserdata']['Groups'])) : '<b color="red">not provided</b>') . '</li></ul></td></tr>'; $body .= '</tbody></table>'; $body .= "<br><br>"; $body .= 'Your Identity Provider responded with attributes:<br>'; $body .= '<table><thead><th>Name</th><th>Values</th></thead><tbody>'; $body .= '<tr><td>Email</td><td><ul><li>' . htmlentities($_SESSION['samlNameId']) . '</li></ul></td></tr>'; foreach ($attributes as $attributeName => $attributeValues) { $body .= '<tr><td>' . htmlentities($attributeName) . '</td><td><ul>'; foreach ($attributeValues as $attributeValue) { $body .= '<li>' . htmlentities($attributeValue) . '</li>'; } $body .= '</ul></td></tr>'; } $body .= '</tbody></table>'; } else { $body .= "<p>You don't have any attribute</p>"; } $body .= '<p><a href="?slo">single logout</a></p>'; } else { $body .= '<p><a href="?sso">single sign on</a></p>'; } $this->response->body = $body; }
/** * 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; } }
/** * Tests the getIdPData method of the OneLogin_Saml2_Settings * * @covers OneLogin_Saml2_Settings::getIdPData */ public function testGetIdPData() { $settingsDir = TEST_ROOT . '/settings/'; include $settingsDir . 'settings1.php'; $settings = new OneLogin_Saml2_Settings($settingsInfo); $idpData = $settings->getIdPData(); $this->assertNotEmpty($idpData); $this->assertArrayHasKey('entityId', $idpData); $this->assertArrayHasKey('singleSignOnService', $idpData); $this->assertArrayHasKey('singleLogoutService', $idpData); $this->assertArrayHasKey('x509cert', $idpData); $this->assertEquals('http://idp.example.com/', $idpData['entityId']); $this->assertEquals('http://idp.example.com/SSOService.php', $idpData['singleSignOnService']['url']); $this->assertEquals('http://idp.example.com/SingleLogoutService.php', $idpData['singleLogoutService']['url']); $x509cert = 'MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo'; $formatedx509cert = OneLogin_Saml2_Utils::formatCert($x509cert); $this->assertEquals($formatedx509cert, $idpData['x509cert']); }
* 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>'; } echo '</ul></td></tr>'; } echo '</tbody></table>'; } else {
<?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'; $auth = new OneLogin_Saml2_Auth(); if (!isset($_SESSION['samlUserdata'])) { $auth->login(); } else { $indexUrl = str_replace('/sso.php', '/index.php', OneLogin_Saml2_Utils::getSelfURLNoQuery()); OneLogin_Saml2_Utils::redirect($indexUrl); }
/** * Extracts nodes that match the query from the DOMDocument (Response Menssage) * * @param string $query Xpath Expresion * * @return DOMNodeList The queried nodes */ private function _query($query) { return OneLogin_Saml2_Utils::query($this->document, $query); }
/** * 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; }
/** * 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']; 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>'; } } $signature = ''; if (isset($security['authnRequestsSigned']) && $security['authnRequestsSigned']) { $key = $this->_settings->getSPkey(); $objKey = new XMLSecurityKey($security['signatureAlgorithm'], array('type' => 'private')); $objKey->loadKey($key, false); $signatureValue = $objKey->signData(time()); $signatureValue = base64_encode($signatureValue); $digestValue = base64_encode(sha1(time())); $x509Cert = $this->_settings->getSPcert(); $x509Cert = OneLogin_Saml2_Utils::formatCert($x509Cert, false); $signature = <<<SIGNATURE <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /> <ds:Reference> <ds:Transforms> <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /> <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /> <ds:DigestValue>{$digestValue}</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>asd{$signatureValue}</ds:SignatureValue> <ds:KeyInfo> <ds:X509Data> <ds:X509Certificate>{$x509Cert}</ds:X509Certificate> </ds:X509Data> </ds:KeyInfo> </ds:Signature> SIGNATURE; } $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> {$signature} <samlp:NameIDPolicy Format="{$nameIDPolicyFormat}" AllowCreate="true" /> {$requestedAuthnStr} </samlp:AuthnRequest> AUTHNREQUEST; $this->_id = $id; $this->_authnRequest = $request; }
/** * Extracts nodes that match the query from the DOMDocument (Response Menssage) * * @param string $query Xpath Expresion * * @return DOMNodeList The queried nodes */ private function _query($query) { if ($this->encrypted) { return OneLogin_Saml2_Utils::query($this->decryptedDocument, $query); } else { return OneLogin_Saml2_Utils::query($this->document, $query); } }
/** * 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()); } }
/** * Validates a signature (Message or Assertion). * * @param string|DomDocument $xml The element we should validate * @param string|null $cert The pubic cert * @param string|null $fingerprint The fingerprint of the public cert */ public static function validateSign($xml, $cert = null, $fingerprint = null) { if ($xml instanceof DOMDocument) { $dom = clone $xml; } else { if ($xml instanceof DOMElement) { $dom = clone $xml->ownerDocument; } else { $dom = new DOMDocument(); $dom = self::loadXML($dom, $xml); } } $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->idKeys = array('ID'); $objDSig = $objXMLSecDSig->locateSignature($dom); if (!$objDSig) { throw new Exception('Cannot locate Signature Node'); } $objKey = $objXMLSecDSig->locateKey(); if (!$objKey) { throw new Exception('We have no idea about the key'); } $objXMLSecDSig->canonicalizeSignedInfo(); try { $retVal = $objXMLSecDSig->validateReference(); } catch (Exception $e) { throw $e; } XMLSecEnc::staticLocateKeyInfo($objKey, $objDSig); if (!empty($cert)) { $objKey->loadKey($cert, false, true); return $objXMLSecDSig->verify($objKey) === 1; } else { $domCert = $objKey->getX509Certificate(); $domCertFingerprint = OneLogin_Saml2_Utils::calculateX509Fingerprint($domCert); if (OneLogin_Saml2_Utils::formatFingerPrint($fingerprint) !== $domCertFingerprint) { return false; } else { $objKey->loadKey($domCert, false, true); return $objXMLSecDSig->verify($objKey) === 1; } } }
/** * Tests the isValid method of the OneLogin_Saml2_Response * Case valid encrypted assertion * * Signed data can't be modified, so Destination will always fail in strict mode * * @covers OneLogin_Saml2_Response::isValid */ public function testIsValidEnc() { $xml = file_get_contents(TEST_ROOT . '/data/responses/double_signed_encrypted_assertion.xml.base64'); $response = new OneLogin_Saml2_Response($this->_settings, $xml); $this->assertTrue($response->isValid()); $xml2 = file_get_contents(TEST_ROOT . '/data/responses/signed_encrypted_assertion.xml.base64'); $response2 = new OneLogin_Saml2_Response($this->_settings, $xml2); $this->assertTrue($response2->isValid()); $xml3 = file_get_contents(TEST_ROOT . '/data/responses/signed_message_encrypted_assertion.xml.base64'); $response3 = new OneLogin_Saml2_Response($this->_settings, $xml3); $this->assertTrue($response3->isValid()); $settingsDir = TEST_ROOT . '/settings/'; include $settingsDir . 'settings1.php'; $settingsInfo['strict'] = true; $settings = new OneLogin_Saml2_Settings($settingsInfo); $xml4 = file_get_contents(TEST_ROOT . '/data/responses/valid_encrypted_assertion.xml.base64'); // In order to avoid the destination problem $plainMessage4 = base64_decode($xml4); $currentURL = OneLogin_Saml2_Utils::getSelfURLNoQuery(); $plainMessage4 = str_replace('http://stuff.com/endpoints/endpoints/acs.php', $currentURL, $plainMessage4); $message4 = base64_encode($plainMessage4); $response4 = new OneLogin_Saml2_Response($settings, $message4); $response4->isValid(); $this->assertContains('No Signature found. SAML Response rejected', $response4->getError()); }
/** * Tests the isValid method of the OneLogin_Saml2_LogoutResponse * * @covers OneLogin_Saml2_LogoutResponse::isValid */ public function testIsValid() { $message = file_get_contents(TEST_ROOT . '/data/logout_responses/logout_response_deflated.xml.base64'); $response = new OneLogin_Saml2_LogoutResponse($this->_settings, $message); $this->assertTrue($response->isValid()); $this->_settings->setStrict(true); $response2 = new OneLogin_Saml2_LogoutResponse($this->_settings, $message); $this->assertFalse($response2->isValid()); $this->assertContains('The LogoutResponse was received at', $response2->getError()); $plainMessage = gzinflate(base64_decode($message)); $currentURL = OneLogin_Saml2_Utils::getSelfURLNoQuery(); $plainMessage = str_replace('http://stuff.com/endpoints/endpoints/sls.php', $currentURL, $plainMessage); $message3 = base64_encode(gzdeflate($plainMessage)); $response3 = new OneLogin_Saml2_LogoutResponse($this->_settings, $message3); $this->assertTrue($response3->isValid()); }
/** * Tests the logout method of the OneLogin_Saml2_Auth class * Case Logout with no parameters. A logout Request is built and redirect executed * * @covers OneLogin_Saml2_Auth::logout * @runInSeparateProcess */ public function testLogout() { try { // The Header of the redirect produces an Exception $this->_auth->logout(); // Do not ever get here $this->assertFalse(true); } catch (Exception $e) { $this->assertContains('Cannot modify header information', $e->getMessage()); $trace = $e->getTrace(); $targetUrl = getUrlFromRedirect($trace); $parsedQuery = getParamsFromUrl($targetUrl); $sloUrl = $this->_settingsInfo['idp']['singleLogoutService']['url']; $this->assertContains($sloUrl, $targetUrl); $this->assertArrayHasKey('SAMLRequest', $parsedQuery); $this->assertArrayHasKey('RelayState', $parsedQuery); $this->assertEquals($parsedQuery['RelayState'], OneLogin_Saml2_Utils::getSelfRoutedURLNoQuery()); } }
/** * Initiates the SLO process. * * @param string $returnTo The target URL the user should be returned to after logout. */ public function logout($returnTo = null) { $sloUrl = $this->getSLOurl(); if (!isset($sloUrl)) { throw new OneLogin_Saml2_Error('The IdP does not support Single Log Out', OneLogin_Saml2_Error::SAML_SINGLE_LOGOUT_NOT_SUPPORTED); } $logoutRequest = new OneLogin_Saml2_LogoutRequest($this->_settings); $samlRequest = $logoutRequest->getRequest(); $parameters = array('SAMLRequest' => $samlRequest); if (!empty($returnTo)) { $parameters['RelayState'] = $returnTo; } else { $parameters['RelayState'] = OneLogin_Saml2_Utils::getSelfURLNoQuery(); } $security = $this->_settings->getSecurityData(); if (isset($security['logoutRequestSigned']) && $security['logoutRequestSigned']) { $signature = $this->buildRequestSignature($samlRequest, $parameters['RelayState']); $parameters['SigAlg'] = XMLSecurityKey::RSA_SHA1; $parameters['Signature'] = $signature; } $this->redirectTo($sloUrl, $parameters); }
/** * Tests the isValid method of the OneLogin_Saml2_LogoutRequest * * @covers OneLogin_Saml2_LogoutRequest::isValid */ public function testIsInValidSign() { $currentURL = OneLogin_Saml2_Utils::getSelfURLNoQuery(); $this->_settings->setStrict(false); $_GET = array('SAMLRequest' => 'lVLBitswEP0Vo7tjeWzJtki8LIRCYLvbNksPewmyPc6K2pJqyXQ/v1LSQlroQi/DMJr33rwZbZ2cJysezNms/gt+X9H55G2etBOXlx1ZFy2MdMoJLWd0wvfieP/xQcCGCrsYb3ozkRvI+wjpHC5eGU2Sw35HTg3lA8hqZFwWFcMKsStpxbEsxoLXeQN9OdY1VAgk+YqLC8gdCUQB7tyKB+281D6UaF6mtEiBPudcABcMXkiyD26Ulv6CevXeOpFlVvlunb5ttEmV3ZjlnGn8YTRO5qx0NuBs8kzpAd829tXeucmR5NH4J/203I8el6gFRUqbFPJnyEV51Wq30by4TLW0/9ZyarYTxt4sBsjUYLMZvRykl1Fxm90SXVkfwx4P++T4KSafVzmpUcVJ/sfSrQZJPphllv79W8WKGtLx0ir8IrVTqD1pT2MH3QAMSs4KTvui71jeFFiwirOmprwPkYW063+5uRq4urHiiC4e8hCX3J5wqAEGaPpw9XB5JmkBdeDqSlkz6CmUXdl0Qae5kv2F/1384wu3PwE=', 'RelayState' => '_1037fbc88ec82ce8e770b2bed1119747bb812a07e6', 'SigAlg' => 'http://www.w3.org/2000/09/xmldsig#rsa-sha1', 'Signature' => 'XCwCyI5cs7WhiJlB5ktSlWxSBxv+6q2xT3c8L7dLV6NQG9LHWhN7gf8qNsahSXfCzA0Ey9dp5BQ0EdRvAk2DIzKmJY6e3hvAIEp1zglHNjzkgcQmZCcrkK9Czi2Y1WkjOwR/WgUTUWsGJAVqVvlRZuS3zk3nxMrLH6f7toyvuJc='); $request = gzinflate(base64_decode($_GET['SAMLRequest'])); $encodedRequest = $_GET['SAMLRequest']; $logoutRequest = new OneLogin_Saml2_LogoutRequest($this->_settings, $encodedRequest); $this->assertTrue($logoutRequest->isValid()); $this->_settings->setStrict(true); $logoutRequest2 = new OneLogin_Saml2_LogoutRequest($this->_settings, $encodedRequest); $this->assertFalse($logoutRequest2->isValid()); $this->assertContains('The LogoutRequest was received at', $logoutRequest2->getError()); $this->_settings->setStrict(false); $oldSignature = $_GET['Signature']; $_GET['Signature'] = 'vfWbbc47PkP3ejx4bjKsRX7lo9Ml1WRoE5J5owF/0mnyKHfSY6XbhO1wwjBV5vWdrUVX+xp6slHyAf4YoAsXFS0qhan6txDiZY4Oec6yE+l10iZbzvie06I4GPak4QrQ4gAyXOSzwCrRmJu4gnpeUxZ6IqKtdrKfAYRAcVf3333='; $logoutRequest3 = new OneLogin_Saml2_LogoutRequest($this->_settings, $encodedRequest); $this->assertFalse($logoutRequest3->isValid()); $this->assertContains('Signature validation failed. Logout Request rejected', $logoutRequest3->getError()); $_GET['Signature'] = $oldSignature; $oldSigAlg = $_GET['SigAlg']; unset($_GET['SigAlg']); $this->assertTrue($logoutRequest3->isValid()); $oldRelayState = $_GET['RelayState']; $_GET['RelayState'] = 'http://example.com/relaystate'; $this->assertFalse($logoutRequest3->isValid()); $this->assertContains('Signature validation failed. Logout Request rejected', $logoutRequest3->getError()); $this->_settings->setStrict(true); $request2 = str_replace('https://pitbulk.no-ip.org/newonelogin/demo1/index.php?sls', $currentURL, $request); $request2 = str_replace('https://pitbulk.no-ip.org/simplesaml/saml2/idp/metadata.php', 'http://idp.example.com/', $request2); $deflatedRequest2 = gzdeflate($request2); $encodedRequest2 = base64_encode($deflatedRequest2); $_GET['SAMLRequest'] = $encodedRequest2; $logoutRequest4 = new OneLogin_Saml2_LogoutRequest($this->_settings, $encodedRequest2); $this->assertFalse($logoutRequest4->isValid()); $this->assertEquals('Signature validation failed. Logout Request rejected', $logoutRequest4->getError()); $this->_settings->setStrict(false); $logoutRequest5 = new OneLogin_Saml2_LogoutRequest($this->_settings, $encodedRequest2); $this->assertFalse($logoutRequest5->isValid()); $this->assertEquals('Signature validation failed. Logout Request rejected', $logoutRequest5->getError()); $_GET['SigAlg'] = 'http://www.w3.org/2000/09/xmldsig#dsa-sha1'; $this->assertFalse($logoutRequest5->isValid()); $this->assertEquals('Invalid signAlg in the recieved Logout Request', $logoutRequest5->getError()); $settingsDir = TEST_ROOT . '/settings/'; include $settingsDir . 'settings1.php'; $settingsInfo['strict'] = true; $settingsInfo['security']['wantMessagesSigned'] = true; $settings = new OneLogin_Saml2_Settings($settingsInfo); $_GET['SigAlg'] = $oldSigAlg; $oldSignature = $_GET['Signature']; unset($_GET['Signature']); $logoutRequest6 = new OneLogin_Saml2_LogoutRequest($settings, $encodedRequest2); $this->assertFalse($logoutRequest6->isValid()); $this->assertEquals('The Message of the Logout Request is not signed and the SP require it', $logoutRequest6->getError()); $_GET['Signature'] = $oldSignature; $settingsInfo['idp']['certFingerprint'] = 'afe71c28ef740bc87425be13a2263d37971da1f9'; unset($settingsInfo['idp']['x509cert']); $settings2 = new OneLogin_Saml2_Settings($settingsInfo); $logoutRequest7 = new OneLogin_Saml2_LogoutRequest($settings2, $encodedRequest2); $this->assertFalse($logoutRequest7->isValid()); $this->assertContains('In order to validate the sign on the Logout Request, the x509cert of the IdP is required', $logoutRequest7->getError()); }
/** * 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; }
$requestID = null; } $auth->processResponse($requestID); $errors = $auth->getErrors(); if (!empty($errors)) { print_r('<p>' . implode(', ', $errors) . '</p>'); } if (!$auth->isAuthenticated()) { echo "<p>Not authenticated</p>"; exit; } $_SESSION['samlUserdata'] = $auth->getAttributes(); $_SESSION['samlNameId'] = $auth->getNameId(); $_SESSION['samlSessionIndex'] = $auth->getSessionIndex(); unset($_SESSION['AuthNRequestID']); if (isset($_POST['RelayState']) && OneLogin_Saml2_Utils::getSelfURL() != $_POST['RelayState']) { $auth->redirectTo($_POST['RelayState']); } } else { if (isset($_GET['sls'])) { if (isset($_SESSION) && isset($_SESSION['LogoutRequestID'])) { $requestID = $_SESSION['LogoutRequestID']; } else { $requestID = null; } $auth->processSLO(false, $requestID); $errors = $auth->getErrors(); if (empty($errors)) { print_r('<p>Sucessfully logged out</p>'); } else { print_r('<p>' . implode(', ', $errors) . '</p>');
/** * Adds the x509 descriptors (sign/encriptation) to the metadata * The same cert will be used for sign/encrypt * * @param string $metadata SAML Metadata XML * @param string $cert x509 cert * * @return string Metadata with KeyDescriptors */ public static function addX509KeyDescriptors($metadata, $cert) { $xml = new DOMDocument(); $xml->preserveWhiteSpace = false; $xml->formatOutput = true; try { $xml = OneLogin_Saml2_Utils::loadXML($xml, $metadata); if (!$xml) { throw new Exception('Error parsing metadata'); } } catch (Exception $e) { throw new Exception('Error parsing metadata. ' . $e->getMessage()); } $formatedCert = OneLogin_Saml2_Utils::formatCert($cert, false); $x509Certificate = $xml->createElementNS(OneLogin_Saml2_Constants::NS_DS, 'X509Certificate', $formatedCert); $keyData = $xml->createElementNS(OneLogin_Saml2_Constants::NS_DS, 'ds:X509Data'); $keyData->appendChild($x509Certificate); $keyInfo = $xml->createElementNS(OneLogin_Saml2_Constants::NS_DS, 'ds:KeyInfo'); $keyInfo->appendChild($keyData); $keyDescriptor = $xml->createElementNS(OneLogin_Saml2_Constants::NS_MD, "md:KeyDescriptor"); $SPSSODescriptor = $xml->getElementsByTagName('SPSSODescriptor')->item(0); $SPSSODescriptor->insertBefore($keyDescriptor->cloneNode(), $SPSSODescriptor->firstChild); $SPSSODescriptor->insertBefore($keyDescriptor->cloneNode(), $SPSSODescriptor->firstChild); $signing = $xml->getElementsByTagName('KeyDescriptor')->item(0); $signing->setAttribute('use', 'signing'); $encryption = $xml->getElementsByTagName('KeyDescriptor')->item(1); $encryption->setAttribute('use', 'encryption'); $signing->appendChild($keyInfo); $encryption->appendChild($keyInfo->cloneNode(true)); return $xml->saveXML(); }
protected function _generateUniqueID() { return OneLogin_Saml2_Utils::generateUniqueID(); }
/** * Tests the builder method of the OneLogin_Saml2_Metadata * * @covers OneLogin_Saml2_Metadata::builder */ public function testBuilderWithAttributeConsumingServiceWithMultipleAttributeValue() { $settingsDir = TEST_ROOT . '/settings/'; include $settingsDir . 'settings4.php'; $settings = new OneLogin_Saml2_Settings($settingsInfo); $spData = $settings->getSPData(); $security = $settings->getSecurityData(); $organization = $settings->getOrganization(); $contacts = $settings->getContacts(); $metadata = OneLogin_Saml2_Metadata::builder($spData, $security['authnRequestsSigned'], $security['wantAssertionsSigned'], null, null, $contacts, $organization); $this->assertContains('<md:ServiceName xml:lang="en">Service Name</md:ServiceName>', $metadata); $this->assertContains('<md:ServiceDescription xml:lang="en">Service Description</md:ServiceDescription>', $metadata); $this->assertContains('<md:RequestedAttribute Name="urn:oid:0.9.2342.19200300.100.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="uid" isRequired="true" />', $metadata); $this->assertContains('<saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">userType</saml:AttributeValue>', $metadata); $this->assertContains('<saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">admin</saml:AttributeValue>', $metadata); $result = \OneLogin_Saml2_Utils::validateXML($metadata, 'saml-schema-metadata-2.0.xsd'); $this->assertInstanceOf('DOMDocument', $result); }