/** * Start a login operation. * * @param array $params Various options to the authentication request. */ public function login(array $params = array()) { if (array_key_exists('KeepPost', $params)) { $keepPost = (bool) $params['KeepPost']; } else { $keepPost = TRUE; } if (!isset($params['ReturnTo']) && !isset($params['ReturnCallback'])) { $params['ReturnTo'] = SimpleSAML_Utilities::selfURL(); } if (isset($params['ReturnTo']) && $keepPost && $_SERVER['REQUEST_METHOD'] === 'POST') { $params['ReturnTo'] = SimpleSAML_Utilities::createPostRedirectLink($params['ReturnTo'], $_POST); } $session = SimpleSAML_Session::getInstance(); $authnRequest = array('IsPassive' => isset($params['isPassive']) ? $params['isPassive'] : FALSE, 'ForceAuthn' => isset($params['ForceAuthn']) ? $params['ForceAuthn'] : FALSE, 'core:State' => $params, 'core:prevSession' => $session->getAuthData($this->authority, 'AuthnInstant'), 'core:authority' => $this->authority); if (isset($params['saml:RequestId'])) { $authnRequest['RequestID'] = $params['saml:RequestId']; } if (isset($params['SPMetadata']['entityid'])) { $authnRequest['Issuer'] = $params['SPMetadata']['entityid']; } if (isset($params['saml:RelayState'])) { $authnRequest['RelayState'] = $params['saml:RelayState']; } if (isset($params['saml:IDPList'])) { $authnRequest['IDPList'] = $params['saml:IDPList']; } $authId = SimpleSAML_Utilities::generateID(); $session->setAuthnRequest('saml2', $authId, $authnRequest); $relayState = SimpleSAML_Module::getModuleURL('core/bwc_resumeauth.php', array('RequestID' => $authId)); $config = SimpleSAML_Configuration::getInstance(); $authurl = '/' . $config->getBaseURL() . $this->auth; SimpleSAML_Utilities::redirect($authurl, array('RelayState' => $relayState, 'AuthId' => $authId, 'protocol' => 'saml2')); }
function __construct(SimpleSAML_Configuration $configuration, SimpleSAML_Metadata_MetaDataStorageHandler $metadatastore) { $this->configuration = $configuration; $this->metadata = $metadatastore; /* Generate request id. */ $this->id = SimpleSAML_Utilities::generateID(); }
function new_access_token($requestToken, $consumer) { SimpleSAML_Logger::info('OAuth new_access_token(' . $requestToken . ',' . $consumer . ')'); $token = new OAuthToken(SimpleSAML_Utilities::generateID(), SimpleSAML_Utilities::generateID()); // SimpleSAML_Logger::info('OAuth new_access_token(' . $requestToken . ',' . $consumer . ',' . $token . ')'); $this->store->set('access', $token->key, $consumer->key, $token, $this->config->getValue('accessTokenDuration', 60 * 60 * 24)); return $token; }
/** * Build the request we will send to the IdP. * * @param array $artifacts The artifacts we will request. * @return string The request, as an XML string. */ private static function buildRequest(array $artifacts) { $msg = '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">' . '<SOAP-ENV:Body>' . '<samlp:Request xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol"' . ' RequestID="' . SimpleSAML_Utilities::generateID() . '"' . ' MajorVersion="1" MinorVersion="1"' . ' IssueInstant="' . SimpleSAML_Utilities::generateTimestamp() . '"' . '>'; foreach ($artifacts as $a) { $msg .= '<samlp:AssertionArtifact>' . htmlspecialchars($a) . '</samlp:AssertionArtifact>'; } $msg .= '</samlp:Request>' . '</SOAP-ENV:Body>' . '</SOAP-ENV:Envelope>'; return $msg; }
function ADFS_GenerateResponse($issuer, $target, $nameid, $attributes) { # $nameid = '*****@*****.**'; $issueInstant = SimpleSAML_Utilities::generateTimestamp(); $notBefore = SimpleSAML_Utilities::generateTimestamp(time() - 30); $assertionExpire = SimpleSAML_Utilities::generateTimestamp(time() + 60 * 5); $assertionID = SimpleSAML_Utilities::generateID(); $nameidFormat = 'http://schemas.xmlsoap.org/claims/UPN'; $result = '<wst:RequestSecurityTokenResponse xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust"> <wst:RequestedSecurityToken> <saml:Assertion Issuer="' . $issuer . '" IssueInstant="' . $issueInstant . '" AssertionID="' . $assertionID . '" MinorVersion="1" MajorVersion="1" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"> <saml:Conditions NotOnOrAfter="' . $assertionExpire . '" NotBefore="' . $notBefore . '"> <saml:AudienceRestrictionCondition> <saml:Audience>' . $target . '</saml:Audience> </saml:AudienceRestrictionCondition> </saml:Conditions> <saml:AuthenticationStatement AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:unspecified" AuthenticationInstant="' . $issueInstant . '"> <saml:Subject> <saml:NameIdentifier Format="' . $nameidFormat . '">' . htmlspecialchars($nameid) . '</saml:NameIdentifier> </saml:Subject> </saml:AuthenticationStatement> <saml:AttributeStatement> <saml:Subject> <saml:NameIdentifier Format="' . $nameidFormat . '">' . htmlspecialchars($nameid) . '</saml:NameIdentifier> </saml:Subject>'; foreach ($attributes as $name => $values) { if (!is_array($values) || count($values) == 0) { continue; } $hasValue = FALSE; $r = '<saml:Attribute AttributeNamespace="http://schemas.xmlsoap.org/claims" AttributeName="' . htmlspecialchars($name) . '">'; foreach ($values as $value) { if (!isset($value) or $value === '') { continue; } $r .= '<saml:AttributeValue>' . htmlspecialchars($value) . '</saml:AttributeValue>'; $hasValue = TRUE; } $r .= '</saml:Attribute>'; if ($hasValue) { $result .= $r; } } $result .= ' </saml:AttributeStatement> </saml:Assertion> </wst:RequestedSecurityToken> <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"><wsa:EndpointReference xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"> <wsa:Address>' . $target . '</wsa:Address> </wsa:EndpointReference></wsp:AppliesTo> </wst:RequestSecurityTokenResponse>'; return $result; }
/** * Retrieve the ID of a state array. * * Note that this function will not save the state. * * @param array &$state The state array. * @param bool $rawId Return a raw ID, without a restart URL. Defaults to FALSE. * @return string Identifier which can be used to retrieve the state later. */ public static function getStateId(&$state, $rawId = FALSE) { assert('is_array($state)'); assert('is_bool($rawId)'); if (!array_key_exists(self::ID, $state)) { $state[self::ID] = SimpleSAML_Utilities::generateID(); } $id = $state[self::ID]; if ($rawId || !array_key_exists(self::RESTART, $state)) { /* Either raw ID or no restart URL. In any case, return the raw ID. */ return $id; } /* We have a restart URL. Return the ID with that URL. */ return $id . ':' . $state[self::RESTART]; }
/** * Save the state. * * This function saves the state, and returns an id which can be used to * retrieve it later. It will also update the $state array with the identifier. * * @param array &$state The login request state. * @param string $stage The current stage in the login process. * @param bool $rawId Return a raw ID, without a restart URL. * @return string Identifier which can be used to retrieve the state later. */ public static function saveState(&$state, $stage, $rawId = FALSE) { assert('is_array($state)'); assert('is_string($stage)'); assert('is_bool($rawId)'); /* Save stage. */ $state[self::STAGE] = $stage; if (!array_key_exists(self::ID, $state)) { $state[self::ID] = SimpleSAML_Utilities::generateID(); } $id = $state[self::ID]; /* Embed the restart URL in the state identifier, if it is available. */ if (array_key_exists(self::RESTART, $state) && !$rawId) { assert('is_string($state[self::RESTART])'); $return = $id . ':' . $state[self::RESTART]; } else { $return = $id; } $serializedState = serialize($state); $session = SimpleSAML_Session::getInstance(); $session->setData('SimpleSAML_Auth_State', $id, $serializedState, 60 * 60); return $return; }
/** * Marks the user as logged in with the specified authority. * * If the user already has logged in, the user will be logged out first. * * @param string $authority The authority the user logged in with. * @param array|NULL $data The authentication data for this authority. */ public function doLogin($authority, array $data = NULL) { assert('is_string($authority)'); assert('is_array($data) || is_null($data)'); SimpleSAML_Logger::debug('Session: doLogin("' . $authority . '")'); $this->dirty = TRUE; if (isset($this->authData[$authority])) { /* We are already logged in. Log the user out first. */ $this->doLogout($authority); } if ($data === NULL) { $data = array(); } $data['Authority'] = $authority; $globalConfig = SimpleSAML_Configuration::getInstance(); if (!isset($data['AuthnInstant'])) { $data['AuthnInstant'] = time(); } $maxSessionExpire = time() + $globalConfig->getInteger('session.duration', 8 * 60 * 60); if (!isset($data['Expire']) || $data['Expire'] > $maxSessionExpire) { /* Unset, or beyond our session lifetime. Clamp it to our maximum session lifetime. */ $data['Expire'] = $maxSessionExpire; } $this->authData[$authority] = $data; $this->authority = $authority; $this->authToken = SimpleSAML_Utilities::generateID(); $sessionHandler = SimpleSAML_SessionHandler::getSessionHandler(); if (!$this->transient && (!empty($data['RememberMe']) || $this->rememberMeExpire) && $globalConfig->getBoolean('session.rememberme.enable', FALSE)) { $this->setRememberMeExpire(); } else { $sessionHandler->setCookie($globalConfig->getString('session.authtoken.cookiename', 'SimpleSAMLAuthToken'), $this->authToken); } }
} function requireOwnership($entry, $userid) { if (!isset($entry['owner'])) { throw new Exception('OAuth Consumer has no owner. Which means no one is granted access, not even you.'); } if ($entry['owner'] !== $userid) { throw new Exception('OAuth Consumer has an owner that is not equal to your userid, hence you are not granted access.'); } } if (array_key_exists('editkey', $_REQUEST)) { $entryc = $store->get('consumers', $_REQUEST['editkey'], ''); $entry = $entryc['value']; requireOwnership($entry, $userid); } else { $entry = array('owner' => $userid, 'key' => SimpleSAML_Utilities::generateID(), 'secret' => SimpleSAML_Utilities::generateID()); } $editor = new sspmod_oauth_Registry(); if (isset($_POST['submit'])) { $editor->checkForm($_POST); $entry = $editor->formToMeta($_POST, array(), array('owner' => $userid)); requireOwnership($entry, $userid); # echo('<pre>Created: '); print_r($entry); exit; $store->set('consumers', $entry['key'], '', $entry); $template = new SimpleSAML_XHTML_Template($config, 'oauth:registry.saved.php'); $template->data['entry'] = $entry; $template->show(); exit; } $form = $editor->metaToForm($entry); $template = new SimpleSAML_XHTML_Template($config, 'oauth:registry.edit.tpl.php');
/** * Create a link which will POST data. * * @param string $destination The destination URL. * @param array $post The name-value pairs which will be posted to the destination. * @return string An URL which can be accessed to post the data. */ public static function createPostRedirectLink($destination, $post) { assert('is_string($destination)'); assert('is_array($post)'); $id = SimpleSAML_Utilities::generateID(); $postData = array('post' => $post, 'url' => $destination); $session = SimpleSAML_Session::getInstance(); $session->setData('core_postdatalink', $id, $postData); return SimpleSAML_Module::getModuleURL('core/postredirect.php', array('RedirId' => $id)); }
/** * Build a authentication response. * * @param array $idp Metadata for the IdP the response is sent from. * @param array $sp Metadata for the SP the response is sent to. * @param string $shire The endpoint on the SP the response is sent to. * @param array|NULL $attributes The attributes which should be included in the response. * @return string The response. */ public function generate(SimpleSAML_Configuration $idp, SimpleSAML_Configuration $sp, $shire, $attributes) { assert('is_string($shire)'); assert('$attributes === NULL || is_array($attributes)'); if ($sp->hasValue('scopedattributes')) { $scopedAttributes = $sp->getArray('scopedattributes'); } elseif ($idp->hasValue('scopedattributes')) { $scopedAttributes = $idp->getArray('scopedattributes'); } else { $scopedAttributes = array(); } $id = SimpleSAML_Utilities::generateID(); $issueInstant = SimpleSAML_Utilities::generateTimestamp(); // 30 seconds timeskew back in time to allow differing clocks. $notBefore = SimpleSAML_Utilities::generateTimestamp(time() - 30); $assertionExpire = SimpleSAML_Utilities::generateTimestamp(time() + 60 * 5); # 5 minutes $assertionid = SimpleSAML_Utilities::generateID(); $spEntityId = $sp->getString('entityid'); $audience = $sp->getString('audience', $spEntityId); $base64 = $sp->getBoolean('base64attributes', FALSE); $namequalifier = $sp->getString('NameQualifier', $spEntityId); $nameid = SimpleSAML_Utilities::generateID(); $subjectNode = '<Subject>' . '<NameIdentifier' . ' Format="urn:mace:shibboleth:1.0:nameIdentifier"' . ' NameQualifier="' . htmlspecialchars($namequalifier) . '"' . '>' . htmlspecialchars($nameid) . '</NameIdentifier>' . '<SubjectConfirmation>' . '<ConfirmationMethod>' . 'urn:oasis:names:tc:SAML:1.0:cm:bearer' . '</ConfirmationMethod>' . '</SubjectConfirmation>' . '</Subject>'; $encodedattributes = ''; if (is_array($attributes)) { $encodedattributes .= '<AttributeStatement>'; $encodedattributes .= $subjectNode; foreach ($attributes as $name => $value) { $encodedattributes .= $this->enc_attribute($name, $value, $base64, $scopedAttributes); } $encodedattributes .= '</AttributeStatement>'; } /* * The SAML 1.1 response message */ $response = '<Response xmlns="urn:oasis:names:tc:SAML:1.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" IssueInstant="' . $issueInstant . '" MajorVersion="1" MinorVersion="1" Recipient="' . htmlspecialchars($shire) . '" ResponseID="' . $id . '"> <Status> <StatusCode Value="samlp:Success" /> </Status> <Assertion xmlns="urn:oasis:names:tc:SAML:1.0:assertion" AssertionID="' . $assertionid . '" IssueInstant="' . $issueInstant . '" Issuer="' . htmlspecialchars($idp->getString('entityid')) . '" MajorVersion="1" MinorVersion="1"> <Conditions NotBefore="' . $notBefore . '" NotOnOrAfter="' . $assertionExpire . '"> <AudienceRestrictionCondition> <Audience>' . htmlspecialchars($audience) . '</Audience> </AudienceRestrictionCondition> </Conditions> <AuthenticationStatement AuthenticationInstant="' . $issueInstant . '" AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:unspecified">' . $subjectNode . ' </AuthenticationStatement> ' . $encodedattributes . ' </Assertion> </Response>'; return $response; }
} $dn = $ldap->searchfordn($ldapconfig['search.base'], $ldapconfig['search.attributes'], $_POST['username']); } else { $dn = str_replace('%username%', $_POST['username'], $ldapconfig['dnpattern']); } $pwd = $_POST['password']; $ldap = new SimpleSAML_Auth_LDAP($ldapconfig['hostname'], $ldapconfig['enable_tls']); if ($pwd == "" or !$ldap->bind($dn, $pwd)) { SimpleSAML_Logger::info('AUTH - ldap-multi: ' . $_POST['username'] . ' failed to authenticate. DN=' . $dn); throw new Exception('Wrong username or password'); } $attributes = $ldap->getAttributes($dn, $ldapconfig['attributes']); SimpleSAML_Logger::info('AUTH - ldap-multi: ' . $_POST['username'] . ' successfully authenticated'); $session->doLogin('login-ldapmulti'); $session->setAttributes($attributes); $session->setNameID(array('value' => SimpleSAML_Utilities::generateID(), 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient')); /** * Create a statistics log entry for every successfull login attempt. * Also log a specific attribute as set in the config: statistics.authlogattr */ $authlogattr = $config->getValue('statistics.authlogattr', null); if ($authlogattr && array_key_exists($authlogattr, $attributes)) { SimpleSAML_Logger::stats('AUTH-login-ldapmulti OK ' . $attributes[$authlogattr][0]); } else { SimpleSAML_Logger::stats('AUTH-login-ldapmulti OK'); } $returnto = $_REQUEST['RelayState']; SimpleSAML_Utilities::redirect($returnto); } catch (Exception $e) { $error = $e->getMessage(); }
/** * Constructor for SAML 2 assertions. * * @param DOMElement|NULL $xml The input assertion. */ public function __construct(DOMElement $xml = NULL) { $this->id = SimpleSAML_Utilities::generateID(); $this->issueInstant = time(); $this->issuer = ''; $this->authnInstant = time(); $this->attributes = array(); $this->nameFormat = SAML2_Const::NAMEFORMAT_UNSPECIFIED; $this->certificates = array(); $this->AuthenticatingAuthority = array(); $this->SubjectConfirmation = array(); if ($xml === NULL) { return; } if (!$xml->hasAttribute('ID')) { throw new Exception('Missing ID attribute on SAML assertion.'); } $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')); $issuer = SAML2_Utils::xpQuery($xml, './saml_assertion:Issuer'); if (empty($issuer)) { throw new Exception('Missing <saml:Issuer> in assertion.'); } $this->issuer = trim($issuer[0]->textContent); $this->parseSubject($xml); $this->parseConditions($xml); $this->parseAuthnStatement($xml); $this->parseAttributes($xml); $this->parseEncryptedAttributes($xml); $this->parseSignature($xml); }
public static function PrepSAMLAssertion(&$saml_xml_request) { // // Gather inputs needed during assembly of SAML Assertion (e.g., keys, certs, timestamps, IDs_ // $DateTimeNow = new DateTime(null, new DateTimeZone("UTC")); $DateTimeNowString = $DateTimeNow->format("Y-m-d\\TH:i:s.B\\Z"); $DateTime15Min = new DateTime(null, new DateTimeZone("UTC")); $DateTime15Min->modify('+900 sec'); $DateTime15MinString = $DateTime15Min->format("Y-m-d\\TH:i:s.B\\Z"); $SAMLParams = array(); $SAMLParams['IssueInstant'] = $DateTimeNowString; $SAMLParams['Issuer'] = SAML_IDENTITY_PROVIDER_ID; $SAMLParams['ID'] = SimpleSAML_Utilities::generateID(); $SAMLParams['NameID'] = SAML_NAME_ID; $SAMLParams['NotBefore'] = $DateTimeNowString; $SAMLParams['NotOnOrAfter'] = $DateTime15MinString; $SAMLParams['AuthnInstant'] = $DateTimeNowString; $SAMLParams['Audience'] = SAML_IDENTITY_PROVIDER_ID; $SAMLParams['x509'] = file_get_contents(SAML_X509_CERT_PATH); $SAMLParams['private_key'] = file_get_contents(SAML_X509_PRIVATE_KEY_PATH); // // Assemble DOM containing correct SAML assertion // $xml = new DOMDocument('1.0', 'utf-8'); // Assertion $assertion = $xml->createElementNS('urn:oasis:names:tc:SAML:2.0:assertion', 'saml2:Assertion'); $assertion->setAttribute('ID', $SAMLParams['ID']); $assertion->setAttribute('Version', '2.0'); $assertion->setAttribute('IssueInstant', $SAMLParams['IssueInstant']); $xml->appendChild($assertion); // Issuer $issuer = $xml->createElement('saml2:Issuer', $SAMLParams['Issuer']); $assertion->appendChild($issuer); // Subject + NameID + SubjectConfirmation $subject = $xml->createElement('saml2:Subject'); $assertion->appendChild($subject); // NameID $nameid = $xml->createElement('saml2:NameID', $SAMLParams['NameID']); $nameid->setAttribute('Format', 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified'); $subject->appendChild($nameid); // SubjectConfirmation $confirmation = $xml->createElement('saml2:SubjectConfirmation'); $confirmation->setAttribute('Method', 'urn:oasis:names:tc:SAML:2.0:cm:bearer'); $subject->appendChild($confirmation); // Conditions + AudienceRestriction + Audience $condition = $xml->createElement('saml2:Conditions'); $condition->setAttribute('NotBefore', $SAMLParams['NotBefore']); $condition->setAttribute('NotOnOrAfter', $SAMLParams['NotOnOrAfter']); $assertion->appendChild($condition); // AudienceRestriction $audiencer = $xml->createElement('saml2:AudienceRestriction'); $condition->appendChild($audiencer); // Audience $audience = $xml->createElement('saml2:Audience', $SAMLParams['Audience']); $audiencer->appendChild($audience); // AuthnStatement + AuthnContext + AuthnContextClassRef $authnstat = $xml->createElement('saml2:AuthnStatement'); $authnstat->setAttribute('AuthnInstant', $SAMLParams['AuthnInstant']); $authnstat->setAttribute('SessionIndex', $SAMLParams['ID']); $assertion->appendChild($authnstat); // AuthnContext $authncontext = $xml->createElement('saml2:AuthnContext'); $authnstat->appendChild($authncontext); // AuthnContextClassRef $authncontext_ref = $xml->createElement('saml2:AuthnContextClassRef', 'urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified'); $authncontext->appendChild($authncontext_ref); //Private KEY $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private')); $objKey->loadKey($SAMLParams['private_key']); //Sign the Assertion $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $objXMLSecDSig->addReferenceList(array($assertion), XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), array('URI' => 'ID', 'overwrite' => false, 'id_name' => 'ID')); $objXMLSecDSig->sign($objKey); $objXMLSecDSig->add509Cert($SAMLParams['x509']); $objXMLSecDSig->insertSignature($assertion, $subject); $saml = $xml->saveXML(); // // Change Reference URI locally (considered changing 'xmlseclibs.php', but // that seemed inappropriate) // preg_match("/<ds:Reference URI=\"#(.+?)\">/is", $saml, $URI); $saml = str_replace("Id=\"" . $URI[1] . "\"", "", $saml); $saml = str_replace($URI[1], $SAMLParams["ID"], $saml); // // Prepare Base64-Encoded SAML Assertion request body based on DOM // $saml = str_replace('<?xml version="1.0" encoding="utf-8"?>', '', $saml); $saml_xml_request = base64_encode(stripslashes($saml)); }
/** * Build an assertion based on information in the metadata. * * @param SimpleSAML_Configuration $srcMetadata The metadata of the sender (IdP). * @param SimpleSAML_Configuration $dstMetadata The metadata of the recipient (SP). * @param array $attributes The attributes of the user * @return SAML2_Assertion The assertion. */ public static function buildAssertion(SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata, array $attributes, $consumerURL) { $signAssertion = $dstMetadata->getBoolean('saml20.sign.assertion', NULL); if ($signAssertion === NULL) { $signAssertion = $srcMetadata->getBoolean('saml20.sign.assertion', TRUE); } $config = SimpleSAML_Configuration::getInstance(); $a = new SAML2_Assertion(); if ($signAssertion) { self::addSign($srcMetadata, $dstMetadata, $a); } $a->setIssuer($srcMetadata->getString('entityid')); $a->setDestination($consumerURL); $a->setValidAudiences(array($dstMetadata->getString('entityid'))); $a->setNotBefore(time() - 30); $assertionLifetime = $dstMetadata->getInteger('assertion.lifetime', NULL); if ($assertionLifetime === NULL) { $assertionLifetime = $srcMetadata->getInteger('assertion.lifetime', 300); } $a->setNotOnOrAfter(time() + $assertionLifetime); $a->setAuthnContext(SAML2_Const::AC_PASSWORD); $sessionLifetime = $config->getInteger('session.duration', 8 * 60 * 60); $a->setSessionNotOnOrAfter(time() + $sessionLifetime); $session = SimpleSAML_Session::getInstance(); $sessionIndex = $session->getSessionIndex(); $a->setSessionIndex($sessionIndex); /* Add attributes. */ if ($dstMetadata->getBoolean('simplesaml.attributes', TRUE)) { $attributeNameFormat = $dstMetadata->getString('AttributeNameFormat', NULL); if ($attributeNameFormat === NULL) { $attributeNameFormat = $srcMetadata->getString('AttributeNameFormat', 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic'); } $a->setAttributeNameFormat($attributeNameFormat); $attributes = self::encodeAttributes($srcMetadata, $dstMetadata, $attributes); $a->setAttributes($attributes); } /* Generate the NameID for the assertion. */ $nameIdFormat = $dstMetadata->getString('NameIDFormat', 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'); $spNameQualifier = $dstMetadata->getString('SPNameQualifier', NULL); if ($spNameQualifier === NULL) { $spNameQualifier = $dstMetadata->getString('entityid'); } if ($nameIdFormat === SAML2_Const::NAMEID_TRANSIENT) { $nameIdValue = SimpleSAML_Utilities::generateID(); } else { $nameIdValue = self::generateNameIdValue($srcMetadata, $dstMetadata, $attributes); } $a->setNameId(array('Format' => $nameIdFormat, 'Value' => $nameIdValue, 'SPNameQualifier' => $spNameQualifier)); return $a; }
} elseif (array_key_exists('ReturnTo', $_GET)) { /* We have a ReturnTo - this is IdP initialized SLO. */ $logoutInfo['RelayState'] = $_GET['ReturnTo']; } else { /* * We have no idea what to do here. It is neither a logout request, a logout * response nor a response from bridged SLO. */ SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutService: No request, response or bridge'); SimpleSAML_Utilities::fatalError($session->getTrackID(), 'SLOSERVICEPARAMS'); } /* First, log out of the current authentication source. */ $authority = $session->getAuthority(); if ($authority !== NULL) { /* We are logged in. */ $bridgedId = SimpleSAML_Utilities::generateID(); $returnTo = SimpleSAML_Utilities::selfURLNoQuery() . '?LogoutID=' . $bridgedId; /* Save the $logoutInfo until we return from the SP. */ saveLogoutInfo($bridgedId); if ($authority === $idpMetadata->getString('auth')) { /* This is probably an authentication source. */ SimpleSAML_Auth_Default::initLogoutReturn($returnTo); } elseif ($authority === 'saml2') { /* SAML 2 SP which isn't an authentication source. */ SimpleSAML_Utilities::redirect('/' . $config->getBaseURL() . 'saml2/sp/initSLO.php', array('RelayState' => $returnTo)); } else { /* A different old-style authentication file. */ $session->doLogout(); } } /*
/** * Register a new session in the datastore. * * @param string $authId The authsource ID. * @param array $nameId The NameID of the user. * @param string|NULL $sessionIndex The SessionIndex of the user. */ public static function addSession($authId, array $nameId, $sessionIndex, $expire) { assert('is_string($authId)'); assert('is_string($sessionIndex) || is_null($sessionIndex)'); assert('is_int($expire)'); if ($sessionIndex === NULL) { /* This IdP apparently did not include a SessionIndex, and thus probably does not * support SLO. We still want to add the session to the data store just in case * it supports SLO, but we don't want an LogoutRequest with a specific * SessionIndex to match this session. We therefore generate our own session index. */ $sessionIndex = SimpleSAML_Utilities::generateID(); } $store = SimpleSAML_Store::getInstance(); if ($store === FALSE) { /* We don't have a datastore. */ return; } /* Normalize NameID. */ ksort($nameId); $strNameId = serialize($nameId); $strNameId = sha1($strNameId); /* Normalize SessionIndex. */ if (strlen($sessionIndex) > 50) { $sessionIndex = sha1($sessionIndex); } $session = SimpleSAML_Session::getInstance(); $sessionId = $session->getSessionId(); if ($store instanceof SimpleSAML_Store_SQL) { self::addSessionSQL($store, $authId, $strNameId, $sessionIndex, $expire, $sessionId); } else { $store->set('saml.LogoutStore', $strNameId . ':' . $sessionIndex, $sessionId, $expire); } }
$defNameId['Format'] = SAML2_Const::NAMEID_TRANSIENT; } if (!array_key_exists('NameQualifier', $defNameId) || $defNameId['NameQualifier'] === NULL) { $defNameId['NameQualifier'] = ''; } if (!array_key_exists('SPNameQualifier', $defNameId) || $defNameId['SPNameQualifier'] === NULL) { $defNameId['SPNameQualifier'] = ''; } if (array_key_exists('dataId', $_REQUEST)) { $dataId = (string) $_REQUEST['dataId']; $data = $session->getData('attributequeryexample:data', $dataId); if ($data == NULL) { $data = array(); } } else { $dataId = SimpleSAML_Utilities::generateID(); $data = array(); } if (array_key_exists('nameIdFormat', $_REQUEST)) { $data['nameIdFormat'] = (string) $_REQUEST['nameIdFormat']; } elseif (!array_key_exists('nameIdFormat', $data)) { $data['nameIdFormat'] = $defNameId['Format']; } if (array_key_exists('nameIdValue', $_REQUEST)) { $data['nameIdValue'] = (string) $_REQUEST['nameIdValue']; } elseif (!array_key_exists('nameIdValue', $data)) { $data['nameIdValue'] = $defNameId['Value']; } if (array_key_exists('nameIdQualifier', $_REQUEST)) { $data['nameIdQualifier'] = (string) $_REQUEST['nameIdQualifier']; } elseif (!array_key_exists('nameIdQualifier', $data)) {
public function registerUser($name, $email) { $sessid = SimpleSAML_Utilities::generateID(); $this->user = new Data_User($this->db); setcookie('foodleSession', $sessid, time() + 60 * 60 * 24 * 90, '/'); $this->user->userid = substr(sha1('sf65d4d5' . $sessid), 0, 10); // this salt does NOT need to be secret. setcookie('foodleEmail', $email, time() + 60 * 60 * 24 * 90, '/'); $this->user->email = $email; setcookie('foodleDisplayName', $name, time() + 60 * 60 * 24 * 90, '/'); $this->user->username = $name; $this->bootstrap = $this->getBootstrap($sessid); $this->sendEmail(); return $this->user; }
/** * Build an assertion based on information in the metadata. * * @param SimpleSAML_Configuration $idpMetadata The metadata of the IdP. * @param SimpleSAML_Configuration $spMetadata The metadata of the SP. * @param array &$state The state array with information about the request. * @return SAML2_Assertion The assertion. */ private static function buildAssertion(SimpleSAML_Configuration $idpMetadata, SimpleSAML_Configuration $spMetadata, array &$state) { assert('isset($state["Attributes"])'); assert('isset($state["saml:ConsumerURL"])'); $signAssertion = $spMetadata->getBoolean('saml20.sign.assertion', NULL); if ($signAssertion === NULL) { $signAssertion = $idpMetadata->getBoolean('saml20.sign.assertion', TRUE); } $config = SimpleSAML_Configuration::getInstance(); $a = new SAML2_Assertion(); if ($signAssertion) { sspmod_saml_Message::addSign($idpMetadata, $spMetadata, $a); } $a->setIssuer($idpMetadata->getString('entityid')); $a->setValidAudiences(array($spMetadata->getString('entityid'))); $a->setNotBefore(time() - 30); $assertionLifetime = $spMetadata->getInteger('assertion.lifetime', NULL); if ($assertionLifetime === NULL) { $assertionLifetime = $idpMetadata->getInteger('assertion.lifetime', 300); } $a->setNotOnOrAfter(time() + $assertionLifetime); if (isset($state['saml:AuthnContextClassRef'])) { $a->setAuthnContext($state['saml:AuthnContextClassRef']); } else { $a->setAuthnContext(SAML2_Const::AC_PASSWORD); } if (isset($state['AuthnInstant'])) { $a->setAuthnInstant($state['AuthnInstant']); } else { /* For backwards compatibility. Remove in version 1.8. */ $session = SimpleSAML_Session::getInstance(); $a->setAuthnInstant($session->getAuthnInstant()); } $sessionLifetime = $config->getInteger('session.duration', 8 * 60 * 60); $a->setSessionNotOnOrAfter(time() + $sessionLifetime); $a->setSessionIndex(SimpleSAML_Utilities::generateID()); $sc = new SAML2_XML_saml_SubjectConfirmation(); $sc->Method = SAML2_Const::CM_BEARER; $sc->SubjectConfirmationData = new SAML2_XML_saml_SubjectConfirmationData(); $sc->SubjectConfirmationData->NotOnOrAfter = time() + $assertionLifetime; $sc->SubjectConfirmationData->Recipient = $state['saml:ConsumerURL']; $sc->SubjectConfirmationData->InResponseTo = $state['saml:RequestId']; $a->setSubjectConfirmation(array($sc)); /* Add attributes. */ if ($spMetadata->getBoolean('simplesaml.attributes', TRUE)) { $attributeNameFormat = $spMetadata->getString('AttributeNameFormat', NULL); if ($attributeNameFormat === NULL) { $attributeNameFormat = $idpMetadata->getString('AttributeNameFormat', 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic'); } $a->setAttributeNameFormat($attributeNameFormat); $attributes = self::encodeAttributes($idpMetadata, $spMetadata, $state['Attributes']); $a->setAttributes($attributes); } /* Generate the NameID for the assertion. */ if (isset($state['saml:NameIDFormat'])) { $nameIdFormat = $state['saml:NameIDFormat']; } else { $nameIdFormat = NULL; } if ($nameIdFormat === NULL || !isset($state['saml:NameID'][$nameIdFormat])) { /* Either not set in request, or not set to a format we supply. Fall back to old generation method. */ $nameIdFormat = $spMetadata->getString('NameIDFormat', 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'); } if (isset($state['saml:NameID'][$nameIdFormat])) { $nameId = $state['saml:NameID'][$nameIdFormat]; $nameId['Format'] = $nameIdFormat; } else { $spNameQualifier = $spMetadata->getString('SPNameQualifier', NULL); if ($spNameQualifier === NULL) { $spNameQualifier = $spMetadata->getString('entityid'); } if ($nameIdFormat === SAML2_Const::NAMEID_TRANSIENT) { /* generate a random id */ $nameIdValue = SimpleSAML_Utilities::generateID(); } else { /* this code will end up generating either a fixed assigned id (via nameid.attribute) or random id if not assigned/configured */ $nameIdValue = self::generateNameIdValue($idpMetadata, $spMetadata, $state); if ($nameIdValue === NULL) { SimpleSAML_Logger::warning('Falling back to transient NameID.'); $nameIdFormat = SAML2_Const::NAMEID_TRANSIENT; $nameIdValue = SimpleSAML_Utilities::generateID(); } } $nameId = array('Format' => $nameIdFormat, 'Value' => $nameIdValue, 'SPNameQualifier' => $spNameQualifier); } $a->setNameId($nameId); return $a; }
function present_attributes($t, $attributes, $nameParent) { $alternate = array('odd', 'even'); $i = 0; $summary = 'summary="' . $t->t('{consent:consent:table_summary}') . '"'; if (strlen($nameParent) > 0) { $parentStr = strtolower($nameParent) . '_'; $str = '<table class="attributes" ' . $summary . '>'; } else { $parentStr = ''; $str = '<table id="table_with_attributes" class="attributes" ' . $summary . '>'; $str .= "\n" . '<caption>' . $t->t('{consent:consent:table_caption}') . '</caption>'; } foreach ($attributes as $name => $value) { $nameraw = $name; $nameTag = '{attributes:attribute_' . $parentStr . str_replace(":", "_", strtolower($name)) . '}'; if ($t->getTag($nameTag) !== NULL) { $name = $t->t($nameTag); } if (preg_match('/^child_/', $nameraw)) { // Insert child table $parentName = preg_replace('/^child_/', '', $nameraw); foreach ($value as $child) { $str .= "\n" . '<tr class="odd"><td style="padding: 2em">' . present_attributes($t, $child, $parentName) . '</td></tr>'; } } else { // Insert values directly $str .= "\n" . '<tr class="' . $alternate[$i++ % 2] . '"><td><span class="attrname">' . htmlspecialchars($name) . '</span>'; $isHidden = in_array($nameraw, $t->data['hiddenAttributes'], TRUE); if ($isHidden) { $hiddenId = SimpleSAML_Utilities::generateID(); $str .= '<div class="attrvalue" style="display: none;" id="hidden_' . $hiddenId . '">'; } else { $str .= '<div class="attrvalue">'; } if (sizeof($value) > 1) { // We hawe several values $str .= '<ul>'; foreach ($value as $listitem) { if ($nameraw === 'jpegPhoto') { $str .= '<li><img src="data:image/jpeg;base64,' . $listitem . '" alt="User photo" /></li>'; } else { $str .= '<li>' . htmlspecialchars($listitem) . '</li>'; } } $str .= '</ul>'; } elseif (isset($value[0])) { // We hawe only one value if ($nameraw === 'jpegPhoto') { $str .= '<img src="data:image/jpeg;base64,' . htmlspecialchars($value[0]) . '" alt="User photo" />'; } else { $str .= htmlspecialchars($value[0]); } } // end of if multivalue $str .= '</div>'; if ($isHidden) { $str .= '<div class="attrvalue consent_showattribute" id="visible_' . $hiddenId . '">'; $str .= '... '; $str .= '<a class="consent_showattributelink" href="javascript:SimpleSAML_show(\'hidden_' . $hiddenId . '\'); SimpleSAML_hide(\'visible_' . $hiddenId . '\');">'; $str .= $t->t('{consent:consent:show_attribute}'); $str .= '</a>'; $str .= '</div>'; } $str .= '</td></tr>'; } // end else: not child table } // end foreach $str .= isset($attributes) ? '</table>' : ''; return $str; }
public static function sendResponse(array $state) { $spMetadata = $state["SPMetadata"]; $spEntityId = $spMetadata['entityid']; $spMetadata = SimpleSAML_Configuration::loadFromArray($spMetadata, '$metadata[' . var_export($spEntityId, TRUE) . ']'); $attributes = $state['Attributes']; $nameidattribute = $spMetadata->getValue('simplesaml.nameidattribute'); if (!empty($nameidattribute)) { if (!array_key_exists($nameidattribute, $attributes)) { throw new Exception('simplesaml.nameidattribute does not exist in resulting attribute set'); } $nameid = $attributes[$nameidattribute][0]; } else { $nameid = SimpleSAML_Utilities::generateID(); } $idp = SimpleSAML_IdP::getByState($state); $idpMetadata = $idp->getConfig(); $idpEntityId = $idpMetadata->getString('entityid'); $idp->addAssociation(array('id' => 'adfs:' . $spEntityId, 'Handler' => 'sspmod_adfs_IdP_ADFS', 'adfs:entityID' => $spEntityId)); $response = sspmod_adfs_IdP_ADFS::ADFS_GenerateResponse($idpEntityId, $spEntityId, $nameid, $attributes); $privateKeyFile = SimpleSAML_Utilities::resolveCert($idpMetadata->getString('privatekey')); $certificateFile = SimpleSAML_Utilities::resolveCert($idpMetadata->getString('certificate')); $wresult = sspmod_adfs_IdP_ADFS::ADFS_SignResponse($response, $privateKeyFile, $certificateFile); $wctx = $state['adfs:wctx']; sspmod_adfs_IdP_ADFS::ADFS_PostResponse($spMetadata->getValue('prp'), $wresult, $wctx); }
/** * Build an assertion based on information in the metadata. * * @param SimpleSAML_Configuration $idpMetadata The metadata of the IdP. * @param SimpleSAML_Configuration $spMetadata The metadata of the SP. * @param array &$state The state array with information about the request. * @return SAML2_Assertion The assertion. */ private static function buildAssertion(SimpleSAML_Configuration $idpMetadata, SimpleSAML_Configuration $spMetadata, array &$state) { assert('isset($state["Attributes"])'); assert('isset($state["saml:ConsumerURL"])'); $signAssertion = $spMetadata->getBoolean('saml20.sign.assertion', NULL); if ($signAssertion === NULL) { $signAssertion = $idpMetadata->getBoolean('saml20.sign.assertion', TRUE); } $config = SimpleSAML_Configuration::getInstance(); $a = new SAML2_Assertion(); if ($signAssertion) { sspmod_saml_Message::addSign($idpMetadata, $spMetadata, $a); } $a->setIssuer($idpMetadata->getString('entityid')); $a->setValidAudiences(array($spMetadata->getString('entityid'))); $a->setNotBefore(time() - 30); $assertionLifetime = $spMetadata->getInteger('assertion.lifetime', NULL); if ($assertionLifetime === NULL) { $assertionLifetime = $idpMetadata->getInteger('assertion.lifetime', 300); } $a->setNotOnOrAfter(time() + $assertionLifetime); if (isset($state['saml:AuthnContextClassRef'])) { $a->setAuthnContext($state['saml:AuthnContextClassRef']); } else { $a->setAuthnContext(SAML2_Const::AC_PASSWORD); } if (isset($state['AuthnInstant'])) { $a->setAuthnInstant($state['AuthnInstant']); } else { /* For backwards compatibility. Remove in version 1.8. */ $session = SimpleSAML_Session::getInstance(); $a->setAuthnInstant($session->getAuthnInstant()); } $sessionLifetime = $config->getInteger('session.duration', 8 * 60 * 60); $a->setSessionNotOnOrAfter(time() + $sessionLifetime); $a->setSessionIndex(SimpleSAML_Utilities::generateID()); $sc = new SAML2_XML_saml_SubjectConfirmation(); $sc->SubjectConfirmationData = new SAML2_XML_saml_SubjectConfirmationData(); $sc->SubjectConfirmationData->NotOnOrAfter = time() + $assertionLifetime; $sc->SubjectConfirmationData->Recipient = $state['saml:ConsumerURL']; $sc->SubjectConfirmationData->InResponseTo = $state['saml:RequestId']; /* ProtcolBinding of SP's <AuthnRequest> overwrites IdP hosted metadata configuration. */ $hokAssertion = NULL; if ($state['saml:Binding'] === SAML2_Const::BINDING_HOK_SSO) { $hokAssertion = TRUE; } if ($hokAssertion === NULL) { $hokAssertion = $idpMetadata->getBoolean('saml20.hok.assertion', FALSE); } if ($hokAssertion) { /* Holder-of-Key */ $sc->Method = SAML2_Const::CM_HOK; if (SimpleSAML_Utilities::isHTTPS()) { if (isset($_SERVER['SSL_CLIENT_CERT']) && !empty($_SERVER['SSL_CLIENT_CERT'])) { /* Extract certificate data (if this is a certificate). */ $clientCert = $_SERVER['SSL_CLIENT_CERT']; $pattern = '/^-----BEGIN CERTIFICATE-----([^-]*)^-----END CERTIFICATE-----/m'; if (preg_match($pattern, $clientCert, $matches)) { /* We have a client certificate from the browser which we add to the HoK assertion. */ $x509Certificate = new SAML2_XML_ds_X509Certificate(); $x509Certificate->certificate = str_replace(array("\r", "\n", " "), '', $matches[1]); $x509Data = new SAML2_XML_ds_X509Data(); $x509Data->data[] = $x509Certificate; $keyInfo = new SAML2_XML_ds_KeyInfo(); $keyInfo->info[] = $x509Data; $sc->SubjectConfirmationData->info[] = $keyInfo; } else { throw new SimpleSAML_Error_Exception('Error creating HoK assertion: No valid client certificate provided during TLS handshake with IdP'); } } else { throw new SimpleSAML_Error_Exception('Error creating HoK assertion: No client certificate provided during TLS handshake with IdP'); } } else { throw new SimpleSAML_Error_Exception('Error creating HoK assertion: No HTTPS connection to IdP, but required for Holder-of-Key SSO'); } } else { /* Bearer */ $sc->Method = SAML2_Const::CM_BEARER; } $a->setSubjectConfirmation(array($sc)); /* Add attributes. */ if ($spMetadata->getBoolean('simplesaml.attributes', TRUE)) { $attributeNameFormat = self::getAttributeNameFormat($idpMetadata, $spMetadata); $a->setAttributeNameFormat($attributeNameFormat); $attributes = self::encodeAttributes($idpMetadata, $spMetadata, $state['Attributes']); $a->setAttributes($attributes); } /* Generate the NameID for the assertion. */ if (isset($state['saml:NameIDFormat'])) { $nameIdFormat = $state['saml:NameIDFormat']; } else { $nameIdFormat = NULL; } if ($nameIdFormat === NULL || !isset($state['saml:NameID'][$nameIdFormat])) { /* Either not set in request, or not set to a format we supply. Fall back to old generation method. */ $nameIdFormat = $spMetadata->getString('NameIDFormat', 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'); } if (isset($state['saml:NameID'][$nameIdFormat])) { $nameId = $state['saml:NameID'][$nameIdFormat]; $nameId['Format'] = $nameIdFormat; } else { $spNameQualifier = $spMetadata->getString('SPNameQualifier', NULL); if ($spNameQualifier === NULL) { $spNameQualifier = $spMetadata->getString('entityid'); } if ($nameIdFormat === SAML2_Const::NAMEID_TRANSIENT) { /* generate a random id */ $nameIdValue = SimpleSAML_Utilities::generateID(); } else { /* this code will end up generating either a fixed assigned id (via nameid.attribute) or random id if not assigned/configured */ $nameIdValue = self::generateNameIdValue($idpMetadata, $spMetadata, $state); if ($nameIdValue === NULL) { SimpleSAML_Logger::warning('Falling back to transient NameID.'); $nameIdFormat = SAML2_Const::NAMEID_TRANSIENT; $nameIdValue = SimpleSAML_Utilities::generateID(); } } $nameId = array('Format' => $nameIdFormat, 'Value' => $nameIdValue, 'SPNameQualifier' => $spNameQualifier); } $state['saml:idp:NameID'] = $nameId; $a->setNameId($nameId); $encryptNameId = $spMetadata->getBoolean('nameid.encryption', NULL); if ($encryptNameId === NULL) { $encryptNameId = $idpMetadata->getBoolean('nameid.encryption', FALSE); } if ($encryptNameId) { $a->encryptNameId(sspmod_saml_Message::getEncryptionKey($spMetadata)); } return $a; }
if (!isset($session) || !$session->isValid($authority)) { /* We don't have a valid session. */ $needAuth = TRUE; } elseif (array_key_exists('NeedAuthentication', $requestcache) && $requestcache['NeedAuthentication']) { /* We have a valid session, but ForceAuthn is on. */ $needAuth = TRUE; } elseif (sizeof($IDPList) > 0 && $session->getidp() !== null && !in_array($session->getidp(), $IDPList)) { /* we do have a valid session but not with one of the scoped idps. */ $needAuth = TRUE; } else { /* We have a valid session. */ $needAuth = FALSE; } if ($needAuth && !$isPassive) { SimpleSAML_Logger::info('SAML2.0 - IdP.SSOService: Will go to authentication module ' . $idpmetadata['auth']); $authId = SimpleSAML_Utilities::generateID(); $session->setAuthnRequest('saml2', $authId, $requestcache); $redirectTo = SimpleSAML_Utilities::selfURLNoQuery() . '?RequestID=' . urlencode($authId); if ($authSource) { /* Authenticate with an AuthSource. */ /* The user will be redirected to this URL if the session is lost. This will cause an * unsoliced authentication response to be sent to the SP. */ $sessionLostParams = array('spentityid' => $requestcache['Issuer']); if (isset($requestcache['RelayState'])) { $sessionLostParams['RelayState'] = $requestcache['RelayState']; } $sessionLostURL = SimpleSAML_Utilities::addURLparameter($metadata->getGenerated('SingleSignOnService', 'saml20-idp-hosted'), $sessionLostParams); $hints = array('SPMetadata' => $metadata->getMetaData($requestcache['Issuer'], 'saml20-sp-remote'), 'IdPMetadata' => $idpmetadata, SimpleSAML_Auth_State::RESTART => $sessionLostURL); SimpleSAML_Auth_Default::initLogin($idpmetadata['auth'], $redirectTo, $redirectTo, $hints); } else {
/** * Get the NameID value. * * @return string|NULL The NameID value. */ protected function getValue(array &$state) { return SimpleSAML_Utilities::generateID(); }
/** * 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. */ } }
/** * Create a link which will POST data to HTTP in a secure way. * * @param string $destination The destination URL. * @param array $post The name-value pairs which will be posted to the destination. * @return string A URL which can be accessed to post the data. */ public static function createHttpPostRedirectLink($destination, $post) { assert('is_string($destination)'); assert('is_array($post)'); $postId = SimpleSAML_Utilities::generateID(); $postData = array('post' => $post, 'url' => $destination); $session = SimpleSAML_Session::getSessionFromRequest(); $session->setData('core_postdatalink', $postId, $postData); $redirInfo = base64_encode(self::aesEncrypt($session->getSessionId() . ':' . $postId)); $url = SimpleSAML_Module::getModuleURL('core/postredirect.php', array('RedirInfo' => $redirInfo)); $url = preg_replace("#^https:#", "http:", $url); return $url; }
/** * Marks the user as logged in with the specified authority. * * If the user already has logged in, the user will be logged out first. * * @param string $authority The authority the user logged in with. * @param array|NULL $data The authentication data for this authority. */ public function doLogin($authority, array $data = NULL) { assert('is_string($authority)'); assert('is_array($data) || is_null($data)'); SimpleSAML_Logger::debug('Session: doLogin("' . $authority . '")'); $this->dirty = TRUE; if (isset($this->authData[$authority])) { /* We are already logged in. Log the user out first. */ $this->doLogout($authority); } if ($data === NULL) { $data = array(); } if (!isset($data['AuthnInstant'])) { $data['AuthnInstant'] = time(); } if (!isset($data['Expire'])) { $globalConfig = SimpleSAML_Configuration::getInstance(); $data['Expire'] = time() + $globalConfig->getInteger('session.duration', 8 * 60 * 60); } $this->authData[$authority] = $data; $this->authority = $authority; $this->authToken = SimpleSAML_Utilities::generateID(); $sessionHandler = SimpleSAML_SessionHandler::getSessionHandler(); $sessionHandler->setCookie('SimpleSAMLAuthToken', $this->authToken); }
throw new Exception('Required URL query parameter [service] not provided. (CAS Server)'); } try { /* Load simpleSAMLphp, configuration and metadata */ $casconfig = SimpleSAML_Configuration::getConfig('module_casserver.php'); $path = $casconfig->resolvePath($casconfig->getValue('ticketcache', 'ticketcache')); $ticketcontent = retrieveTicket($ticket, $path); $usernamefield = $casconfig->getValue('attrname', 'eduPersonPrincipalName'); $dosendattributes = $casconfig->getValue('attributes', FALSE); $attributes = $ticketcontent['attributes']; $pgtiouxml = ""; if ($ticketcontent['service'] == $service && $ticketcontent['forceAuthn'] == $forceAuthn && array_key_exists($usernamefield, $attributes) && $ticketcontent['validbefore'] > time()) { if (isset($_GET['pgtUrl'])) { $pgtUrl = $_GET['pgtUrl']; $pgtiou = str_replace('_', 'PGTIOU-', SimpleSAML_Utilities::generateID()); $pgt = str_replace('_', 'PGT-', SimpleSAML_Utilities::generateID()); $content = array('attributes' => $attributes, 'forceAuthn' => false, 'proxies' => array_merge(array($service), $ticketcontent['proxies']), 'validbefore' => time() + 60); SimpleSAML_Utilities::fetch($pgtUrl . '?pgtIou=' . $pgtiou . '&pgtId=' . $pgt); storeTicket($pgt, $path, $content); $pgtiouxml = "\n<cas:proxyGrantingTicket>{$pgtiou}</cas:proxyGrantingTicket>\n"; } $proxiesxml = join("\n", array_map(create_function('$a', 'return "<cas:proxy>$a</cas:proxy>";'), $ticketcontent['proxies'])); if ($proxiesxml) { $proxiesxml = "<cas:proxies>\n{$proxiesxml}\n</cas:proxies>\n"; } returnResponse('YES', $function, $attributes[$usernamefield][0], $dosendattributes ? $attributes : array(), $pgtiouxml . $proxiesxml); } else { returnResponse('NO', $function); } } catch (Exception $e) { returnResponse('NO', $function, $e->getMessage());
/** * Build a authentication response. * * @param array $idp Metadata for the IdP the response is sent from. * @param array $sp Metadata for the SP the response is sent to. * @param string $shire The endpoint on the SP the response is sent to. * @param array|NULL $attributes The attributes which should be included in the response. * @return string The response. */ public function generate($idp, $sp, $shire, $attributes) { assert('is_array($idp)'); assert('is_array($sp)'); assert('is_string($shire)'); assert('$attributes === NULL || is_array($attributes)'); if (array_key_exists('scopedattributes', $sp)) { $scopedAttributes = $sp['scopedattributes']; $scopedAttributesSource = 'the shib13-sp-remote sp \'' . $sp['entityid'] . '\''; } elseif (array_key_exists('scopedattributes', $idp)) { $scopedAttributes = $idp['scopedattributes']; $scopedAttributesSource = 'the shib13-idp-hosted idp \'' . $idp['entityid'] . '\''; } else { $scopedAttributes = array(); } if (!is_array($scopedAttributes)) { throw new Exception('The \'scopedattributes\' option in ' . $scopedAttributesSource . ' should be an array of attribute names.'); } foreach ($scopedAttributes as $an) { if (!is_string($an)) { throw new Exception('Invalid attribute name in the \'scopedattributes\' option in ' . $scopedAttributesSource . ': ' . var_export($an, TRUE)); } } $id = SimpleSAML_Utilities::generateID(); $issueInstant = SimpleSAML_Utilities::generateTimestamp(); // 30 seconds timeskew back in time to allow differing clocks. $notBefore = SimpleSAML_Utilities::generateTimestamp(time() - 30); $assertionExpire = SimpleSAML_Utilities::generateTimestamp(time() + 60 * 5); # 5 minutes $assertionid = SimpleSAML_Utilities::generateID(); $audience = isset($sp['audience']) ? $sp['audience'] : $sp['entityid']; $base64 = isset($sp['base64attributes']) ? $sp['base64attributes'] : false; $namequalifier = isset($sp['NameQualifier']) ? $sp['NameQualifier'] : $sp['entityid']; $nameid = SimpleSAML_Utilities::generateID(); $subjectNode = '<Subject>' . '<NameIdentifier' . ' Format="urn:mace:shibboleth:1.0:nameIdentifier"' . ' NameQualifier="' . htmlspecialchars($namequalifier) . '"' . '>' . htmlspecialchars($nameid) . '</NameIdentifier>' . '<SubjectConfirmation>' . '<ConfirmationMethod>' . 'urn:oasis:names:tc:SAML:1.0:cm:bearer' . '</ConfirmationMethod>' . '</SubjectConfirmation>' . '</Subject>'; $encodedattributes = ''; if (is_array($attributes)) { $encodedattributes .= '<AttributeStatement>'; $encodedattributes .= $subjectNode; foreach ($attributes as $name => $value) { $encodedattributes .= $this->enc_attribute($name, $value, $base64, $scopedAttributes); } $encodedattributes .= '</AttributeStatement>'; } /* * The SAML 1.1 response message */ $response = '<Response xmlns="urn:oasis:names:tc:SAML:1.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" IssueInstant="' . $issueInstant . '" MajorVersion="1" MinorVersion="1" Recipient="' . htmlspecialchars($shire) . '" ResponseID="' . $id . '"> <Status> <StatusCode Value="samlp:Success" /> </Status> <Assertion xmlns="urn:oasis:names:tc:SAML:1.0:assertion" AssertionID="' . $assertionid . '" IssueInstant="' . $issueInstant . '" Issuer="' . htmlspecialchars($idp['entityid']) . '" MajorVersion="1" MinorVersion="1"> <Conditions NotBefore="' . $notBefore . '" NotOnOrAfter="' . $assertionExpire . '"> <AudienceRestrictionCondition> <Audience>' . htmlspecialchars($audience) . '</Audience> </AudienceRestrictionCondition> </Conditions> <AuthenticationStatement AuthenticationInstant="' . $issueInstant . '" AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:unspecified">' . $subjectNode . ' </AuthenticationStatement> ' . $encodedattributes . ' </Assertion> </Response>'; return $response; }