public function process(&$state) { assert('is_array($state)'); if (empty($state['Expire']) || empty($state['Authority'])) { return; } $now = time(); $delta = $state['Expire'] - $now; $globalConfig = SimpleSAML_Configuration::getInstance(); $sessionDuration = $globalConfig->getInteger('session.duration', 8 * 60 * 60); /* Extend only if half of session duration already passed */ if ($delta >= $sessionDuration * 0.5) { return; } /* Update authority expire time */ $session = SimpleSAML_Session::getInstance(); $session->setAuthorityExpire($state['Authority']); /* Update session cookies duration */ /* If remember me is active */ $rememberMeExpire = $session->getRememberMeExpire(); if (!empty($state['RememberMe']) && $rememberMeExpire !== NULL && $globalConfig->getBoolean('session.rememberme.enable', FALSE)) { $session->setRememberMeExpire(); return; } /* Or if session lifetime is more than zero */ $sessionHandler = SimpleSAML_SessionHandler::getSessionHandler(); $cookieParams = $sessionHandler->getCookieParams(); if ($cookieParams['lifetime'] > 0) { $session->updateSessionCookies(); } }
/** * When login is complete, save the SSPAuthentication object to the session */ public final function loginComplete() { //Use the same session as SimpleSAMLphp to avoid session state loss Session::start(SimpleSAML_Session::getInstance()->getSessionId()); Session::set('ssp_current_auth_source', $this->getAuthSource()->getAuthId()); Session::set('ssp_current_auth_class', get_class($this)); Session::save(); }
/** * Display this error. * * This method displays a standard simpleSAMLphp error page and exits. */ public function show() { $this->setHTTPCode(); $session = SimpleSAML_Session::getInstance(); if ($this->cause !== NULL) { $e = $this->cause; } else { $e = $this; } SimpleSAML_Utilities::fatalError($session->getTrackID(), $this->errorCode, $e); }
public static function checkLoggedAndSameAuth() { $session = SimpleSAML_Session::getInstance(); if ($session->isAuthenticated()) { $uregconf = SimpleSAML_Configuration::getConfig('module_selfregister.php'); /* Get a reference to our authentication source. */ $asId = $uregconf->getString('auth'); if ($session->getAuthority() == $asId) { return new SimpleSAML_Auth_Simple($asId); } } return false; }
/** * Apply filter to add the UID attribute. * * @param array &$request The current request */ public function process(&$request) { assert('is_array($request)'); assert('array_key_exists("Attributes", $request)'); $authModule = NULL; // Fetch Auth module if (array_key_exists("SimpleSAML_Auth_State.stage", $request)) { $authStage = implode(":", array_slice(explode(':', $request["SimpleSAML_Auth_State.stage"]), 0, -1)); $authId = $authStage . ':AuthId'; $authModule = $request[$authId]; } else { if (isset($request['AuthnInstant']) && isset($request['Expire'])) { // Probably dealing with a cached response $cachedAuthModule = SimpleSAML_Session::getInstance()->getData(sspmod_multiauth_Auth_Source_MultiAuth::SESSION_SOURCE, 'multi'); if ($cachedAuthModule) { $authModule = $cachedAuthModule; } } } if (!isset($authModule)) { throw new Exception("Auth module not found?!?!"); } $attributes =& $request['Attributes']; $filter = null; // Set or replace the filter attribute if (array_key_exists($authModule, $this->map)) { $filter = $this->map[$authModule]; } switch ($filter) { case 'GOOGLE': $attributes['uid'] = $this->_useEmailAsUid($attributes); break; case 'YAHOO': $attributes['uid'] = $this->_useEmailAsUid($attributes); break; case 'HYVES': if (!array_key_exists('openid.local_id', $attributes)) { throw new Exception('No local id attribute provided! Cannot use it as UID'); } $attributes['uid'] = str_replace('.hyves.nl/', '', str_replace('http://', '', $attributes['openid.local_id'])); break; default: if (!array_key_exists('uid', $attributes)) { throw new Exception('No UID set?!?!'); } break; } }
/** * Constructor * * Note that the person is tied to a session and a simplesaml configuration * here */ function __construct($person = NULL) { parent::__construct($person); /* Find the path to simpelsamlphp and run the autoloader */ try { $sspdir = Config::get_config('simplesaml_path'); } catch (KeyNotFoundException $knfe) { echo "Cannot find path to simplesaml. This install is not valid. Aborting.<br />\n"; Logger::logEvent(LOG_ALERT, "Confusa_Auth_IdP", "__construct()", "Trying to instantiate SimpleSAMLphp without a configured path."); exit(0); } require_once $sspdir . '/lib/_autoload.php'; SimpleSAML_Configuration::setConfigDir($sspdir . '/config'); /* start a session needed for the IdP-based AuthN approach */ $this->as = new SimpleSAML_Auth_Simple('default-sp'); $this->session = SimpleSAML_Session::getInstance(); }
/** * Log-in using Facebook platform * * @param array &$state Information about the current authentication. */ public function authenticate(&$state) { assert('is_array($state)'); /* We are going to need the authId in order to retrieve this authentication source later. */ $state[self::AUTHID] = $this->authId; $stateID = SimpleSAML_Auth_State::saveState($state, self::STAGE_INIT); // SimpleSAML_Logger::debug('facebook auth state id = ' . $stateID); $consumer = new sspmod_oauth_Consumer($this->key, $this->secret); // Get the request token $requestToken = $consumer->getRequestToken('http://twitter.com/oauth/request_token'); SimpleSAML_Logger::debug("Got a request token from the OAuth service provider [" . $requestToken->key . "] with the secret [" . $requestToken->secret . "]"); $oauthState = array('requestToken' => serialize($requestToken), 'stateid' => $stateID); $session = SimpleSAML_Session::getInstance(); $session->setData('oauth', 'oauth', $oauthState); // Authorize the request token $consumer->getAuthorizeRequest('http://twitter.com/oauth/authenticate', $requestToken); }
/** * Initializes this discovery service. * * The constructor does the parsing of the request. If this is an invalid request, it will * throw an exception. * * @param array $metadataSets Array with metadata sets we find remote entities in. * @param string $instance The name of this instance of the discovery service. */ public function __construct(array $metadataSets, $instance) { assert('is_string($instance)'); /* Initialize standard classes. */ $this->config = SimpleSAML_Configuration::getInstance(); $this->metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $this->session = SimpleSAML_Session::getInstance(); $this->instance = $instance; $this->metadataSets = $metadataSets; $this->log('Accessing discovery service.'); /* Standard discovery service parameters. */ if (!array_key_exists('entityID', $_GET)) { throw new Exception('Missing parameter: entityID'); } else { $this->spEntityId = $_GET['entityID']; } if (!array_key_exists('returnIDParam', $_GET)) { $this->returnIdParam = 'entityID'; } else { $this->returnIdParam = $_GET['returnIDParam']; } $this->log('returnIdParam initially set to [' . $this->returnIdParam . ']'); if (!array_key_exists('return', $_GET)) { throw new Exception('Missing parameter: return'); } else { $this->returnURL = $_GET['return']; } $this->isPassive = FALSE; if (array_key_exists('isPassive', $_GET)) { if ($_GET['isPassive'] === 'true') { $this->isPassive = TRUE; } } $this->log('isPassive initially set to [' . ($this->isPassive ? 'TRUE' : 'FALSE') . ']'); if (array_key_exists('IdPentityID', $_GET)) { $this->setIdPentityID = $_GET['IdPentityID']; } else { $this->setIdPentityID = NULL; } if (array_key_exists('IDPList', $_GET)) { $this->scopedIDPList = $_GET['IDPList']; } }
public function authenticate(TokenInterface $token) { /** @var string $authenticationType */ $authenticationType = $this->config->getValue('auth', 'login-admin'); if (php_sapi_name() === 'cli') { return $this->getTokenForUsername($authenticationType); } $session = \SimpleSAML_Session::getInstance(); if (!$session->isValid($authenticationType)) { throw new AuthenticationException("Authsource '{$authenticationType}' is invalid"); } /** @var string $userIdAttributeName */ $userIdAttributeName = $this->config->getValue('useridattr', 'eduPersonPrincipalName'); // Check if userid exists $attributes = $session->getAttributes(); if (!isset($attributes[$userIdAttributeName])) { throw new AuthenticationException("Attribute '{$userIdAttributeName}' with User ID is missing."); } return $this->getTokenForUsername($attributes[$userIdAttributeName][0]); }
/** * Apply filter to add the SchacHomeOrganization attribute. * * @param array &$request The current request */ public function process(&$request) { assert('is_array($request)'); assert('array_key_exists("Attributes", $request)'); $authModule = NULL; // Fetch Auth module if (array_key_exists("SimpleSAML_Auth_State.stage", $request)) { $authStage = implode(":", array_slice(explode(':', $request["SimpleSAML_Auth_State.stage"]), 0, -1)); $authId = $authStage . ':AuthId'; $authModule = $request[$authId]; } else { if (isset($request['AuthnInstant']) && isset($request['Expire'])) { // Probably dealing with a cached response $cachedAuthModule = SimpleSAML_Session::getInstance()->getData(sspmod_multiauth_Auth_Source_MultiAuth::SESSION_SOURCE, 'multi'); if ($cachedAuthModule) { $authModule = $cachedAuthModule; } } } if (!isset($authModule)) { throw new Exception("Auth module not found?!?!"); } $attributes =& $request['Attributes']; // Set or replace the schacHomeOrganization attribute if (array_key_exists($authModule, $this->map)) { $schacHomeOrganization = $this->map[$authModule]; if (isset($schacHomeOrganization)) { $attributes["schacHomeOrganization"] = $schacHomeOrganization; return; } } if (array_key_exists(DEFAULT_SCHACHOMEORG, $this->map)) { throw new Exception("No default schacHomeOrganization?!?"); } $attributes["schacHomeOrganization"] = $this->map[DEFAULT_SCHACHOMEORG]; }
/** * Show the error to the user. * * This function does not return. */ public function show() { header('HTTP/1.0 500 Internal Server Error'); $errorData = $this->saveError(); $session = SimpleSAML_Session::getInstance(); $attributes = $session->getAttributes(); if (isset($attributes['mail'][0])) { $email = $attributes['mail'][0]; } else { $email = ''; } $globalConfig = SimpleSAML_Configuration::getInstance(); $t = new SimpleSAML_XHTML_Template($globalConfig, 'core:no_state.tpl.php'); /* Enable error reporting if we have a valid technical contact email. */ if ($globalConfig->getString('technicalcontact_email', '*****@*****.**') !== '*****@*****.**') { /* Enable error reporting. */ $baseurl = SimpleSAML_Utilities::getBaseURL(); $t->data['errorReportAddress'] = $baseurl . 'errorreport.php'; $t->data['reportId'] = $errorData['reportId']; $t->data['email'] = $email; } $t->show(); exit; }
/** * Process a authentication response. * * This function saves the state, and redirects the user to the page where the user * can authorize the release of the attributes. * * @param array $state The state of the response. */ public function process(&$state) { assert('is_array($state)'); assert('array_key_exists("UserID", $state)'); assert('array_key_exists("Destination", $state)'); assert('array_key_exists("entityid", $state["Destination"])'); assert('array_key_exists("metadata-set", $state["Destination"])'); assert('array_key_exists("entityid", $state["Source"])'); assert('array_key_exists("metadata-set", $state["Source"])'); $session = SimpleSAML_Session::getInstance(); $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); /* If the consent module is active on a bridge $state['saml:sp:IdP'] will contain * an entry id for the remote IdP. If not, then the * consent module is active on a local IdP and nothing needs to be done. */ if (isset($state['saml:sp:IdP'])) { $idpmeta = $metadata->getMetaData($state['saml:sp:IdP'], 'saml20-idp-remote'); $state['Source'] = $idpmeta; } elseif ($session->getIdP() !== NULL) { /* For backwards compatibility. TODO: Remove in version 1.8. */ $idpmeta = $metadata->getMetaData($session->getIdP(), 'saml20-idp-remote'); $state['Source'] = $idpmeta; } if ($this->store !== NULL) { // Do not use consent if disabled on source entity if (isset($state['Source']['consent.disable']) && in_array($state['Destination']['entityid'], $state['Source']['consent.disable'])) { SimpleSAML_Logger::debug('Consent - Consent disabled for entity ' . $state['Destination']['entityid']); return; } $source = $state['Source']['metadata-set'] . '|' . $state['Source']['entityid']; $destination = $state['Destination']['metadata-set'] . '|' . $state['Destination']['entityid']; SimpleSAML_Logger::debug('Consent - userid : ' . $state['UserID']); SimpleSAML_Logger::debug('Consent - source : ' . $source); SimpleSAML_Logger::debug('Consent - destination : ' . $destination); $userId = self::getHashedUserID($state['UserID'], $source); $targetedId = self::getTargetedID($state['UserID'], $source, $destination); $attributeSet = self::getAttributeHash($state['Attributes'], $this->includeValues); SimpleSAML_Logger::debug('Consent - hasConsent() : [' . $userId . '|' . $targetedId . '|' . $attributeSet . ']'); if ($this->store->hasConsent($userId, $targetedId, $attributeSet)) { SimpleSAML_Logger::stats('consent found'); /* Consent already given. */ return; } SimpleSAML_Logger::stats('consent notfound'); $state['consent:store'] = $this->store; $state['consent:store.userId'] = $userId; $state['consent:store.destination'] = $targetedId; $state['consent:store.attributeSet'] = $attributeSet; } else { SimpleSAML_Logger::stats('consent nostorage'); } $state['consent:focus'] = $this->focus; $state['consent:checked'] = $this->checked; $state['consent:hiddenAttributes'] = $this->hiddenAttributes; /* User interaction nessesary. Throw exception on isPassive request */ if (isset($state['isPassive']) && $state['isPassive'] == TRUE) { throw new SimpleSAML_Error_NoPassive('Unable to give consent on passive request.'); } /* Save state and redirect. */ $id = SimpleSAML_Auth_State::saveState($state, 'consent:request'); $url = SimpleSAML_Module::getModuleURL('consent/getconsent.php'); SimpleSAML_Utilities::redirect($url, array('StateId' => $id)); }
/** * Call a logout callback based on association. * * This function calls a logout callback based on an association saved with * addLogoutCallback(...). * * This function always returns. * * @param string $assoc The logout association which should be called. */ protected function callLogoutCallback($assoc) { assert('is_string($assoc)'); $id = strlen($this->authId) . ':' . $this->authId . $assoc; $session = SimpleSAML_Session::getInstance(); $data = $session->getData('SimpleSAML_Auth_Source.LogoutCallbacks', $id); if ($data === NULL) { /* FIXME: fix for IdP-first flow (issue 397) -> reevaluate logout callback infrastructure */ $session->doLogout($this->authId); return; } assert('is_array($data)'); assert('array_key_exists("callback", $data)'); assert('array_key_exists("state", $data)'); $callback = $data['callback']; $callbackState = $data['state']; call_user_func($callback, $callbackState); }
/** * @return SimpleSAML_Session */ public function getSession() { return SimpleSAML_Session::getInstance(); }
/** * Check for session cookie, and show missing-cookie page if it is missing. * * @param string|NULL $retryURL The URL the user should access to retry the operation. */ public static function checkCookie($retryURL = NULL) { assert('is_string($retryURL) || is_null($retryURL)'); $session = SimpleSAML_Session::getInstance(); if ($session->hasSessionCookie()) { return; } /* We didn't have a session cookie. Redirect to the no-cookie page. */ $url = SimpleSAML_Module::getModuleURL('core/no_cookie.php'); if ($retryURL !== NULL) { $url = self::addURLParameter($url, array('retryURL' => $retryURL)); } self::redirectTrustedURL($url); }
/** * Tries to retrieve the configured auth data (see internal->authData) from * its' methods and make it availabe in the global context for later usage * by the configured methodSetupFile. */ private function retrieveAuthData() { global $authData; $authData = array(); $libName = $this->config['internal']['authLib']; $attributes = $this->config['internal']['authData']; $skipped = false; switch ($libName) { /* * SHIBBOLETH */ case 'shibboleth': if ($this->config['debug']['logRawAuthLibAttibuteData']) { wfDebugLog('MultiAuthPlugin', __METHOD__ . ': ' . "Shibboleth:\n" . print_r($_SERVER, true)); } foreach ($attributes as $attribute) { if (isset($_SERVER[$attribute])) { $authData[$attribute] = $_SERVER[$attribute]; } else { $authData[$attribute] = ''; } } break; /* * SIMPLESAMLPHP */ /* * SIMPLESAMLPHP */ case 'simplesamlphp': $ssphpPath = $this->config['paths']['libs']['simplesamlphp']; if (file_exists($ssphpPath . "/www/_include.php")) { // load simpleSAMLphp library require_once $ssphpPath . "/www/_include.php"; // Load simpleSAMLphp configuration and session. $config = SimpleSAML_Configuration::getInstance(); $session = SimpleSAML_Session::getInstance(); $ssphpAttrs = array(); if ($session->isValid('saml2')) { // retrieve attributes $ssphpAttrs = $session->getAttributes(); if ($this->config['debug']['logRawAuthLibAttibuteData']) { wfDebugLog('MultiAuthPlugin', __METHOD__ . ': ' . "SimpleSAMLphp:\n" . print_r($ssphpAttrs, true)); } } else { wfDebugLog('MultiAuthPlugin', __METHOD__ . ': ' . "No valid session found."); } foreach ($attributes as $attribute) { if (isset($ssphpAttrs["urn:mace:dir:attribute-def:" . $attribute][0])) { $authData[$attribute] = $ssphpAttrs["urn:mace:dir:attribute-def:" . $attribute][0]; } else { $authData[$attribute] = ''; } } } else { wfDebugLog('MultiAuthPlugin', __METHOD__ . ': ' . "Could not load SimpleSAMLphp lib from '{$ssphpPath}'."); } break; /* * UNKNOWN/INVALID LIBRARY */ /* * UNKNOWN/INVALID LIBRARY */ default: wfDebugLog('MultiAuthPlugin', __METHOD__ . ': ' . "Skipped unknown authentication library '{$libName}'."); $skipped = true; // set attributes to '' for the unknown lib foreach ($attributes as $attribute) { $authData[$attribute] = ''; } } if (!$skipped && $this->config['debug']['logRetrievedAttributeData']) { wfDebugLog('MultiAuthPlugin', __METHOD__ . ': ' . "" . print_r($authData, true)); } }
/** * 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; }
/** * Delete a key from the session store. * * @param string $key The key we should delete. */ public function del($key) { assert('is_string($key)'); $session = SimpleSAML_Session::getInstance(); $session->deleteData('openid.session', $key); }
/** * Call a logout callback based on association. * * This function calls a logout callback based on an association saved with * addLogoutCallback(...). * * This function always returns. * * @param string $assoc The logout association which should be called. */ protected function callLogoutCallback($assoc) { assert('is_string($assoc)'); $id = strlen($this->authId) . ':' . $this->authId . $assoc; $session = SimpleSAML_Session::getInstance(); $data = $session->getData('SimpleSAML_Auth_Source.LogoutCallbacks', $id); if ($data === NULL) { return; } assert('is_array($data)'); assert('array_key_exists("callback", $data)'); assert('array_key_exists("state", $data)'); $callback = $data['callback']; $callbackState = $data['state']; call_user_func($callback, $callbackState); }
/** * Retrieve all authentication data. * * @return array|NULL All persistent authentication data, or NULL if we aren't authenticated. */ public function getAuthDataArray() { if (!$this->isAuthenticated()) { return NULL; } $session = SimpleSAML_Session::getInstance(); return $session->getAuthState($this->authSource); }
/** * Retrieve attributes of the current user. * * This function will retrieve the attributes of the current user if * the user is authenticated. If the user isn't authenticated, it will * return an empty array. * * @return array The users attributes. */ public function getAttributes() { if (!$this->isAuthenticated()) { /* Not authenticated. */ return array(); } /* Authenticated. */ $session = SimpleSAML_Session::getInstance(); return $session->getAttributes(); }
<?php require_once '../../www/_include.php'; $config = SimpleSAML_Configuration::getInstance(); $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $session = SimpleSAML_Session::getInstance(); $ldapconfigfile = $config->getBaseDir() . 'config/ldapmulti.php'; require_once $ldapconfigfile; SimpleSAML_Logger::info('AUTH - ldap-multi: Accessing auth endpoint login-ldapmulti'); if (empty($session)) { SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NOSESSION'); } $error = null; $attributes = array(); /* Load the RelayState argument. The RelayState argument contains the address * we should redirect the user to after a successful authentication. */ if (!array_key_exists('RelayState', $_REQUEST)) { SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NORELAYSTATE'); } if (isset($_POST['username'])) { try { $ldapconfig = $ldapmulti[$_POST['org']]; if ($ldapconfig['search.enable'] === TRUE) { if (!$ldap->bind($ldapconfig['search.username'], $ldapconfig['search.password'])) { throw new Exception('Error authenticating using search username & password.'); } $dn = $ldap->searchfordn($ldapconfig['search.base'], $ldapconfig['search.attributes'], $_POST['username']); } else { $dn = str_replace('%username%', $_POST['username'], $ldapconfig['dnpattern']); }
/** * Retrieve the trackid we should use for logging. * * It is used to avoid infinite recursion between the logger class and the session class. * * @return The trackid we should use for logging, or 'NA' if we detect recursion. */ private static function getTrackId() { if (self::$trackid === self::$TRACKID_FETCHING) { /* Recursion detected. */ return 'NA'; } if (self::$trackid === NULL) { /* No trackid yet, fetch it from the session class. */ /* Mark it as currently being fetched. */ self::$trackid = self::$TRACKID_FETCHING; /* Get the current session. This could cause recursion back to the logger class. */ $session = SimpleSAML_Session::getInstance(); /* Update the trackid. */ self::$trackid = $session->getTrackId(); } assert('is_string(self::$trackid)'); return self::$trackid; }
/** * 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; }
/** * Handle a unsoliced login operations. * * This function creates a session from the received information. It * will then redirect to the given URL. * * This is used to handle IdP initiated SSO. * * @param string $authId The id of the authentication source that received the request. * @param array $state A state array. * @param string $redirectTo The URL we should redirect the user to after * updating the session. */ public static function handleUnsolicedAuth($authId, array $state, $redirectTo) { assert('is_string($authId)'); assert('is_string($redirectTo)'); $session = SimpleSAML_Session::getInstance(); $session->doLogin($authId); if (array_key_exists('Attributes', $state)) { $session->setAttributes($state['Attributes']); } else { $session->setAttributes(array()); } if (array_key_exists('Expires', $state)) { $session->setSessionDuration($state['Expires'] - time()); } if (array_key_exists('LogoutState', $state)) { $session->setLogoutState($state['LogoutState']); } SimpleSAML_Utilities::redirect($redirectTo); }
public function getAttributes() { /* Load simpleSAMLphp, configuration and metadata */ $this->sspconfig = SimpleSAML_Configuration::getInstance(); $this->config = SimpleSAML_Configuration::getInstance('foodle'); $session = SimpleSAML_Session::getInstance(); $authsource = $this->config->getString('auth', 'default-sp'); if ($session->isValid('twitter')) { $authsource = 'twitter'; } if ($session->isValid('facebook')) { $authsource = 'facebook'; } $this->as = new SimpleSAML_Auth_Simple($authsource); /* Check if valid local session exists.. */ if ($this->as->isAuthenticated()) { $attrs = $this->as->getAttributes(); $attrs['idp'] = array($this->as->getAuthData('saml:sp:IdP')); return $attrs; } return FALSE; }
/** * Delete state. * * This function deletes the given state to prevent the user from reusing it later. * * @param array &$state The state which should be deleted. */ public static function deleteState(&$state) { assert('is_array($state)'); if (!array_key_exists(self::ID, $state)) { /* This state hasn't been saved. */ return; } SimpleSAML_Logger::debug('Deleting state: ' . var_export($state[self::ID], TRUE)); $session = SimpleSAML_Session::getInstance(); $session->deleteData('SimpleSAML_Auth_State', $state[self::ID]); }
/** * The user is authenticated. * * @param array $state The authentication request state arrray. */ public static function postAuth(array $state) { $idp = SimpleSAML_IdP::getByState($state); if (!$idp->isAuthenticated()) { throw new SimpleSAML_Error_Exception('Not authenticated.'); } $state['Attributes'] = $idp->authSource->getAttributes(); if (isset($state['SPMetadata'])) { $spMetadata = $state['SPMetadata']; } else { $spMetadata = array(); } if (isset($state['core:SP'])) { $session = SimpleSAML_Session::getInstance(); $previousSSOTime = $session->getData('core:idp-ssotime', $state['core:IdP'] . ';' . $state['core:SP']); if ($previousSSOTime !== NULL) { $state['PreviousSSOTimestamp'] = $previousSSOTime; } } $idpMetadata = $idp->getConfig()->toArray(); $pc = new SimpleSAML_Auth_ProcessingChain($idpMetadata, $spMetadata, 'idp'); $state['ReturnCall'] = array('SimpleSAML_IdP', 'postAuthProc'); $state['Destination'] = $spMetadata; $state['Source'] = $idpMetadata; $pc->processState($state); self::postAuthProc($state); }
/** * Delete state. * * This function deletes the given state to prevent the user from reusing it later. * * @param array &$state The state which should be deleted. */ public static function deleteState(&$state) { assert('is_array($state)'); if (!array_key_exists(self::ID, $state)) { /* This state hasn't been saved. */ return; } $session = SimpleSAML_Session::getInstance(); $session->deleteData('SimpleSAML_Auth_State', $state[self::ID]); }
/** * 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); } }