public function testGenerateID() { // check that it always starts with an underscore $this->assertStringStartsWith('_', SimpleSAML\Utils\Random::generateID()); // check the length $this->assertEquals(SimpleSAML\Utils\Random::ID_LENGTH, strlen(SimpleSAML\Utils\Random::generateID())); }
/** * 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\Utils\Random::generateID() . '"' . ' MajorVersion="1" MinorVersion="1"' . ' IssueInstant="' . SimpleSAML\Utils\Time::generateTimestamp() . '"' . '>'; foreach ($artifacts as $a) { $msg .= '<samlp:AssertionArtifact>' . htmlspecialchars($a) . '</samlp:AssertionArtifact>'; } $msg .= '</samlp:Request>' . '</SOAP-ENV:Body>' . '</SOAP-ENV:Envelope>'; return $msg; }
/** * 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. * * @throws \SimpleSAML\Error\CannotSetCookie If the authentication token cannot be set for some reason. */ 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->markDirty(); 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; } // check if we have non-serializable attribute values foreach ($data['Attributes'] as $attribute => $values) { foreach ($values as $idx => $value) { if (is_string($value) || is_int($value)) { continue; } // at this point, this should be a DOMNodeList object... if (!is_a($value, 'DOMNodeList')) { continue; } /* @var \DOMNodeList $value */ if ($value->length === 0) { continue; } // create an AttributeValue object and save it to 'RawAttributes', using same attribute name and index $attrval = new \SAML2\XML\saml\AttributeValue($value->item(0)->parentNode); $data['RawAttributes'][$attribute][$idx] = $attrval; } } $this->authData[$authority] = $data; $this->authToken = SimpleSAML\Utils\Random::generateID(); $sessionHandler = SimpleSAML_SessionHandler::getSessionHandler(); if (!$this->transient && (!empty($data['RememberMe']) || $this->rememberMeExpire) && $globalConfig->getBoolean('session.rememberme.enable', false)) { $this->setRememberMeExpire(); } else { try { SimpleSAML\Utils\HTTP::setCookie($globalConfig->getString('session.authtoken.cookiename', 'SimpleSAMLAuthToken'), $this->authToken, $sessionHandler->getCookieParams()); } catch (SimpleSAML\Error\CannotSetCookie $e) { /* * Something went wrong when setting the auth token. We cannot recover from this, so we better log a * message and throw an exception. The user is not properly logged in anyway, so clear all login * information from the session. */ unset($this->authToken); unset($this->authData[$authority]); \SimpleSAML\Logger::error('Cannot set authentication token cookie: ' . $e->getMessage()); throw $e; } } }
/** * @param $content array * @return array */ public function createProxyTicket(array $content) { $id = str_replace('_', 'PT-', SimpleSAML\Utils\Random::generateID()); $expiresAt = time() + $this->proxyTicketExpireTime; return array_merge(array('id' => $id, 'validBefore' => $expiresAt), $content); }
/** * 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\Utils\Random::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]; }
} 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\Utils\Random::generateID(), 'secret' => SimpleSAML\Utils\Random::generateID()); } $editor = new sspmod_oauth_Registry(); if (isset($_POST['submit'])) { $editor->checkForm($_POST); $entry = $editor->formToMeta($_POST, array(), array('owner' => $userid)); requireOwnership($entry, $userid); $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'); $template->data['form'] = $form;
/** * Get the NameID value. * * @param array $state The state array. * @return string|null The NameID value. */ protected function getValue(array &$state) { return SimpleSAML\Utils\Random::generateID(); }
/** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::getPOSTRedirectURL() instead. */ public static function createHttpPostRedirectLink($destination, $post) { assert('is_string($destination)'); assert('is_array($post)'); $postId = SimpleSAML\Utils\Random::generateID(); $postData = array('post' => $post, 'url' => $destination); $session = SimpleSAML_Session::getSessionFromRequest(); $session->setData('core_postdatalink', $postId, $postData); $redirInfo = base64_encode(SimpleSAML\Utils\Crypto::aesEncrypt($session->getSessionId() . ':' . $postId)); $url = SimpleSAML_Module::getModuleURL('core/postredirect.php', array('RedirInfo' => $redirInfo)); $url = preg_replace("#^https:#", "http:", $url); return $url; }
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\Utils\Random::generateID()); $pgt = str_replace('_', 'PGT-', SimpleSAML\Utils\Random::generateID()); $content = array('attributes' => $attributes, 'forceAuthn' => false, 'proxies' => array_merge(array($service), $ticketcontent['proxies']), 'validbefore' => time() + 60); \SimpleSAML\Utils\HTTP::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());
function new_access_token($requestToken, $consumer, $verifier = null) { SimpleSAML\Logger::info('OAuth new_access_token(' . $requestToken . ',' . $consumer . ')'); $accestoken = new OAuthToken(SimpleSAML\Utils\Random::generateID(), SimpleSAML\Utils\Random::generateID()); $this->store->set('access', $accestoken->key, $consumer->key, $accestoken, $this->config->getValue('accessTokenDuration', 60 * 60 * 24)); return $accestoken; }
private function generateID($prefix) { return $prefix . substr(SimpleSAML\Utils\Random::generateID(), 1); }
/** * 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"])'); $now = time(); $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($now - 30); $assertionLifetime = $spMetadata->getInteger('assertion.lifetime', NULL); if ($assertionLifetime === NULL) { $assertionLifetime = $idpMetadata->getInteger('assertion.lifetime', 300); } $a->setNotOnOrAfter($now + $assertionLifetime); if (isset($state['saml:AuthnContextClassRef'])) { $a->setAuthnContext($state['saml:AuthnContextClassRef']); } else { $a->setAuthnContext(SAML2_Const::AC_PASSWORD); } $sessionStart = $now; if (isset($state['AuthnInstant'])) { $a->setAuthnInstant($state['AuthnInstant']); $sessionStart = $state['AuthnInstant']; } $sessionLifetime = $config->getInteger('session.duration', 8 * 60 * 60); $a->setSessionNotOnOrAfter($sessionStart + $sessionLifetime); $a->setSessionIndex(SimpleSAML\Utils\Random::generateID()); $sc = new SAML2_XML_saml_SubjectConfirmation(); $sc->SubjectConfirmationData = new SAML2_XML_saml_SubjectConfirmationData(); $sc->SubjectConfirmationData->NotOnOrAfter = $now + $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\Utils\HTTP::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', NULL); if ($nameIdFormat === NULL) { $nameIdFormat = $idpMetadata->getString('NameIDFormat', SAML2_Const::NAMEID_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\Utils\Random::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\Utils\Random::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; }
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\Utils\Random::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\Utils\Config::getCertPath($idpMetadata->getString('privatekey')); $certificateFile = \SimpleSAML\Utils\Config::getCertPath($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); }
/** * 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\Utils\Random::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::getSessionFromRequest(); $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); } }
require_once '_include.php'; try { // load SimpleSAMLphp configuration $globalConfig = SimpleSAML_Configuration::getInstance(); // check if this module is enabled if (!$globalConfig->getBoolean('enable.authmemcookie', false)) { throw new SimpleSAML_Error_Error('NOACCESS'); } // load Auth MemCookie configuration $amc = SimpleSAML_AuthMemCookie::getInstance(); $sourceId = $amc->getAuthSource(); $s = new SimpleSAML_Auth_Simple($sourceId); // check if the user is authorized. We attempt to authenticate the user if not $s->requireAuth(); // generate session id and save it in a cookie $sessionID = SimpleSAML\Utils\Random::generateID(); $cookieName = $amc->getCookieName(); $sessionHandler = SimpleSAML_SessionHandler::getSessionHandler(); $sessionHandler->setCookie($cookieName, $sessionID); // generate the authentication information $attributes = $s->getAttributes(); $authData = array(); // username $usernameAttr = $amc->getUsernameAttr(); if (!array_key_exists($usernameAttr, $attributes)) { throw new Exception("The user doesn't have an attribute named '" . $usernameAttr . "'. This attribute is expected to contain the username."); } $authData['UserName'] = $attributes[$usernameAttr]; // groups $groupsAttr = $amc->getGroupsAttr(); if ($groupsAttr !== null) {
/** * Recursive attribute array listing function * * @param SimpleSAML_XHTML_Template $t Template object * @param array $attributes Attributes to be presented * @param string $nameParent Name of parent element * * @return string HTML representation of the attributes */ 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; $name = $t->getAttributeTranslation($parentStr . $nameraw); 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\Utils\Random::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,' . htmlspecialchars($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; $str .= '\'); 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; }
* service * renew * gateway * */ if (!array_key_exists('service', $_GET)) { throw new Exception('Required URL query parameter [service] not provided. (CAS Server)'); } $service = $_GET['service']; $forceAuthn = isset($_GET['renew']) && $_GET['renew']; $isPassive = isset($_GET['gateway']) && $_GET['gateway']; $config = SimpleSAML_Configuration::getInstance(); $casconfig = SimpleSAML_Configuration::getConfig('module_casserver.php'); $legal_service_urls = $casconfig->getValue('legal_service_urls'); if (!checkServiceURL($service, $legal_service_urls)) { throw new Exception('Service parameter provided to CAS server is not listed as a legal service: [service] = ' . $service); } $auth = $casconfig->getValue('auth', 'saml2'); if (!in_array($auth, array('saml2', 'shib13'))) { throw new Exception('CAS Service configured to use [auth] = ' . $auth . ' only [saml2,shib13] is legal.'); } $as = new SimpleSAML_Auth_Simple($auth); if (!$as->isAuthenticated()) { $params = array('ForceAuthn' => $forceAuthn, 'isPassive' => $isPassive); $as->login($params); } $attributes = $as->getAttributes(); $path = $casconfig->resolvePath($casconfig->getValue('ticketcache', '/tmp')); $ticket = str_replace('_', 'ST-', SimpleSAML\Utils\Random::generateID()); storeTicket($ticket, $path, array('service' => $service, 'forceAuthn' => $forceAuthn, 'attributes' => $attributes, 'proxies' => array(), 'validbefore' => time() + 5)); \SimpleSAML\Utils\HTTP::redirectTrustedURL(\SimpleSAML\Utils\HTTP::addURLParameters($service, array('ticket' => $ticket)));
/** * 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\Utils\Random::generateID(); $issueInstant = SimpleSAML\Utils\Time::generateTimestamp(); // 30 seconds timeskew back in time to allow differing clocks. $notBefore = SimpleSAML\Utils\Time::generateTimestamp(time() - 30); $assertionExpire = SimpleSAML\Utils\Time::generateTimestamp(time() + 60 * 5); # 5 minutes $assertionid = SimpleSAML\Utils\Random::generateID(); $spEntityId = $sp->getString('entityid'); $audience = $sp->getString('audience', $spEntityId); $base64 = $sp->getBoolean('base64attributes', FALSE); $namequalifier = $sp->getString('NameQualifier', $spEntityId); $nameid = SimpleSAML\Utils\Random::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; }
/** * 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->markDirty(); 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->authToken = SimpleSAML\Utils\Random::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); } }