/** * @param string $saml_response Base64 Encoded SAML * * @throws Exception When no assertions are found or signature in invalid */ public function load_saml_response($saml_response) { $response_element = SAML2_DOMDocumentFactory::fromString(base64_decode($saml_response))->documentElement; $signature_info = SAML2_Utils::validateElement($response_element); SAML2_Utils::validateSignature($signature_info, $this->security_key); $response = SAML2_StatusResponse::fromXML($response_element); $this->destination = $response->getDestination(); $assertions = $response->getAssertions(); $this->assertions = $assertions; }
/** * @param string $saml_request Base64 Encoded SAML * * @throws Exception When signature in invalid */ public function load_saml_request($saml_request) { $request_element = SAML2_DOMDocumentFactory::fromString(base64_decode($saml_request))->documentElement; $signature_info = SAML2_Utils::validateElement($request_element); SAML2_Utils::validateSignature($signature_info, $this->security_key); /** @var SAML2_LogoutRequest $request */ $request = SAML2_LogoutRequest::fromXML($request_element); $request->decryptNameId($this->security_key); $name_id = $request->getNameId(); $this->notOnOrAfter = $request->getNotOnOrAfter(); $this->name = $name_id ? $name_id['Value'] : null; $this->session_index = $request->getSessionIndex(); $this->destination = $request->getDestination(); }
/** * Initialize the helper class. * * @param DOMElement|NULL $xml The XML element which may be signed. */ protected function __construct(DOMElement $xml = NULL) { $this->certificates = array(); $this->validators = array(); if ($xml === NULL) { return; } /* Validate the signature element of the message. */ try { $sig = SAML2_Utils::validateElement($xml); if ($sig !== FALSE) { $this->certificates = $sig['Certificates']; $this->validators[] = array('Function' => array('SAML2_Utils', 'validateSignature'), 'Data' => $sig); } } catch (Exception $e) { /* Ignore signature validation errors. */ } }
/** * Parse signature on assertion. * * @param DOMElement $xml The assertion XML element. */ private function parseSignature(DOMElement $xml) { /* Validate the signature element of the message. */ $sig = SAML2_Utils::validateElement($xml); if ($sig !== FALSE) { $this->certificates = $sig['Certificates']; $this->signatureData = $sig; } }
/** * Initialize a message. * * This constructor takes an optional parameter with a DOMElement. If this * parameter is given, the message will be initialized with data from that * XML element. * * If no XML element is given, the message is initialized with suitable * default values. * * @param string $tagName The tag name of the root element. * @param DOMElement|NULL $xml The input message. */ protected function __construct($tagName, DOMElement $xml = NULL) { assert('is_string($tagName)'); $this->tagName = $tagName; $this->id = SimpleSAML_Utilities::generateID(); $this->issueInstant = time(); $this->certificates = array(); $this->validators = array(); if ($xml === NULL) { return; } if (!$xml->hasAttribute('ID')) { throw new Exception('Missing ID attribute on SAML message.'); } $this->id = $xml->getAttribute('ID'); if ($xml->getAttribute('Version') !== '2.0') { /* Currently a very strict check. */ throw new Exception('Unsupported version: ' . $xml->getAttribute('Version')); } $this->issueInstant = SimpleSAML_Utilities::parseSAML2Time($xml->getAttribute('IssueInstant')); if ($xml->hasAttribute('Destination')) { $this->destination = $xml->getAttribute('Destination'); } $issuer = SAML2_Utils::xpQuery($xml, './saml_assertion:Issuer'); if (!empty($issuer)) { $this->issuer = trim($issuer[0]->textContent); } /* Validate the signature element of the message. */ try { $sig = SAML2_Utils::validateElement($xml); if ($sig !== FALSE) { $this->certificates = $sig['Certificates']; $this->validators[] = array('Function' => array('SAML2_Utils', 'validateSignature'), 'Data' => $sig); } } catch (Exception $e) { /* Ignore signature validation errors. */ } }
/** * Front controller for LaunchKey Native/White Label authentication * * * @param WP_User $user Unused parameter always passed first by authenticate filter * @param string $username Username specified by the user in the login screen * @param string $password Password specifiedby the user in the login screen * * @since 1.0.0 * @return WP_User */ public function authenticate($user, $username, $password) { if (empty($user) && empty($username) && empty($password) && !empty($_REQUEST['SAMLResponse'])) { $response_element = SAML2_DOMDocumentFactory::fromString(base64_decode($_REQUEST['SAMLResponse']))->documentElement; $signature_info = SAML2_Utils::validateElement($response_element); try { SAML2_Utils::validateSignature($signature_info, $this->security_key); $response = SAML2_StatusResponse::fromXML($response_element); /** @var SAML2_Assertion[] $assertions */ $assertions = $response->getAssertions(); if (empty($assertions)) { throw new Exception("No assertions in SAML response"); } $assertion = $assertions[0]; $name_id = $assertion->getNameId(); $username = $name_id['Value']; $session_id = $assertion->getSessionIndex(); // Find the user by login $user = $this->wp_facade->get_user_by('login', $username); // If we don't have a user, create one if (!$user instanceof WP_User) { $attributes = $assertion->getAttributes(); $user_data = array('user_login' => $username, 'user_pass' => '', 'role' => empty($attributes['role']) ? false : $this->translate_role($attributes['role'][0])); $user_id = $this->wp_facade->wp_insert_user($user_data); // Unset the password - wp_insert_user always generates a hash - it's misleading $this->wp_facade->wp_update_user(array('ID' => $user_id, 'user_pass' => '')); $user = new WP_User($user_id); } // Set the SSO session so we know we are logged in via SSSO $this->wp_facade->update_user_meta($user->ID, 'launchkey_sso_session', $session_id); } catch (Exception $e) { $this->wp_facade->wp_redirect($this->error_url); exit; } return $user; } }