Created
September 10, 2013 23:42
-
-
Save littlefyr/6517301 to your computer and use it in GitHub Desktop.
A couple sets of changes to get http://wordpress.org/plugins/saml-20-single-sign-on/developers/ working with OKTA. lib\classes\saml_client.php
saml\modules\saml\lib\Auth\Source\SP.php Your mileage may vary
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class SAML_Client | |
{ | |
private $saml; | |
private $opt; | |
private $secretsauce; | |
function __construct() | |
{ | |
$this->settings = new SAML_Settings(); | |
require_once(constant('SAMLAUTH_ROOT') . '/saml/lib/_autoload.php'); | |
if( $this->settings->get_enabled() ) | |
{ | |
$this->saml = new SimpleSAML_Auth_Simple((string)get_current_blog_id()); | |
add_action('wp_authenticate',array($this,'authenticate')); | |
add_action('wp_logout',array($this,'logout')); | |
add_action('login_init',array($this,'login_page')); | |
} | |
// Hash to generate password for SAML users. | |
// This is never actually used by the user, but we need to know what it is, and it needs to be consistent | |
// WARNING: If the WP AUTH_KEY is changed, all SAML users will be unable to login! In cases where this is | |
// actually desired, such as an intrusion, you must delete SAML users or manually set their passwords. | |
// it's messy, so be careful! | |
$this->secretsauce = constant('AUTH_KEY'); | |
} | |
/** | |
* Handle the login page. | |
*/ | |
public function login_page() | |
{ | |
$final = (isset($_REQUEST["redirect_to"])) ? $_REQUEST["redirect_to"] : site_url(); | |
$this->authenticate($final); | |
} | |
/** | |
* Authenticates the user using SAML | |
* | |
* @return void | |
*/ | |
public function authenticate($redirect_to = '') | |
{ | |
if( isset($_GET['loggedout']) && $_GET['loggedout'] == 'true' ) | |
{ | |
header('Location: ' . get_option('siteurl')); | |
exit(); | |
} | |
else | |
{ | |
if (trim($redirect_to) == false) { | |
$redirect_to = SimpleSAML_Utilities::selfURL(); | |
} | |
$this->saml->requireAuth( array('ReturnTo' => $redirect_to)); | |
$attrs = $this->saml->getAttributes(); | |
if(array_key_exists($this->settings->get_attribute('username'), $attrs) ) | |
{ | |
$username = $attrs[$this->settings->get_attribute('username')][0]; | |
if(get_user_by('login',$username)) | |
{ | |
$this->simulate_signon($username, $redirect_to); | |
} | |
else | |
{ | |
$this->new_user($attrs, $redirect_to); | |
} | |
} | |
else | |
{ | |
die('A username was not provided.'); | |
} | |
} | |
} | |
/** | |
* Sends the user to the SAML Logout URL (using SLO if available) and then redirects to the site homepage | |
* | |
* @return void | |
*/ | |
public function logout() | |
{ | |
$this->saml->logout( get_option('siteurl') ); | |
} | |
/** | |
* Creates a new user in the WordPress database using attributes from the IdP | |
* | |
* @param array $attrs The array of attributes created by SimpleSAMLPHP | |
* @return void | |
*/ | |
private function new_user($attrs, $redirect_to) | |
{ | |
if( array_key_exists($this->settings->get_attribute('username'),$attrs) ) | |
{ | |
$login = (array_key_exists($this->settings->get_attribute('username'),$attrs)) ? $attrs[$this->settings->get_attribute('username')][0] : 'NULL'; | |
$email = (array_key_exists($this->settings->get_attribute('email'),$attrs)) ? $attrs[$this->settings->get_attribute('email')][0] : ''; | |
$first_name = (array_key_exists($this->settings->get_attribute('firstname'),$attrs)) ? $attrs[$this->settings->get_attribute('firstname')][0] : ''; | |
$last_name = (array_key_exists($this->settings->get_attribute('lastname'),$attrs)) ? $attrs[$this->settings->get_attribute('lastname')][0] : ''; | |
$display_name = $first_name . ' ' . $last_name; | |
} | |
else | |
{ | |
die('A username was not provided.'); | |
} | |
$role = $this->update_role(); | |
if( $role !== false ) | |
{ | |
$user_opts = array( | |
'user_login' => $login , | |
'user_pass' => $this->user_password($login,$this->secretsauce) , | |
'user_email' => $email , | |
'first_name' => $first_name , | |
'last_name' => $last_name , | |
'display_name' => $display_name , | |
'role' => $role | |
); | |
wp_insert_user($user_opts); | |
$this->simulate_signon($login, $redirect_to); | |
} | |
else | |
{ | |
die('The website administrator has not given you permission to log in.'); | |
} | |
} | |
/** | |
* Authenticates the user with WordPress using wp_signon() | |
* | |
* @param string $username The user to log in as. | |
* @return void | |
*/ | |
private function simulate_signon($username, $redirect_to) | |
{ | |
remove_filter('wp_authenticate',array($this,'authenticate')); | |
$this->update_role(); | |
$login = array( | |
'user_login' => $username, | |
'user_password' => $this->user_password($username,$this->secretsauce), | |
'remember' => false | |
); | |
$use_ssl = ( defined('FORCE_SSL_ADMIN') && constant('FORCE_SSL_ADMIN') === true ) ? true : ''; | |
$result = wp_signon($login,$use_ssl); | |
if(is_wp_error($result)) | |
{ | |
echo $result->get_error_message(); | |
exit(); | |
} | |
else | |
{ | |
wp_redirect($redirect_to); | |
// wp_redirect(get_admin_url()); | |
exit(); | |
} | |
} | |
/** | |
* Updates a user's role if their current one doesn't match the attributes provided by the IdP | |
* | |
* @return string | |
*/ | |
private function update_role() | |
{ | |
$attrs = $this->saml->getAttributes(); | |
if(array_key_exists($this->settings->get_attribute('groups'), $attrs) ) | |
{ | |
if( in_array($this->settings->get_group('admin'),$attrs[$this->settings->get_attribute('groups')]) ) | |
{ | |
$role = 'administrator'; | |
} | |
elseif( in_array($this->settings->get_group('editor'),$attrs[$this->settings->get_attribute('groups')]) ) | |
{ | |
$role = 'editor'; | |
} | |
elseif( in_array($this->settings->get_group('author'),$attrs[$this->settings->get_attribute('groups')]) ) | |
{ | |
$role = 'author'; | |
} | |
elseif( in_array($this->settings->get_group('contributor'),$attrs[$this->settings->get_attribute('groups')]) ) | |
{ | |
$role = 'contributor'; | |
} | |
elseif( in_array($this->settings->get_group('subscriber'),$attrs[$this->settings->get_attribute('groups')]) ) | |
{ | |
$role = 'subscriber'; | |
} | |
elseif( $this->settings->get_allow_unlisted_users() ) | |
{ | |
$role = 'subscriber'; | |
} | |
else | |
{ | |
$role = false; | |
} | |
} | |
else | |
{ | |
$role = false; | |
} | |
$user = get_user_by('login',$attrs[$this->settings->get_attribute('username')][0]); | |
if($user) | |
{ | |
$user->set_role($role); | |
} | |
return $role; | |
} | |
/** | |
* Generates a SHA-256 HMAC hash using the username and secret key | |
* | |
* @param string $value the user's username | |
* @param string $key a secret key | |
* @return string | |
*/ | |
private function user_password($value,$key) | |
{ | |
$hash = hash_hmac('sha256',$value,$key); | |
return $hash; | |
} | |
public function show_password_fields($show_password_fields) { | |
return false; | |
} | |
public function disable_function() { | |
die('Disabled'); | |
} | |
} // End of Class SamlAuth |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class sspmod_saml_Auth_Source_SP extends SimpleSAML_Auth_Source { | |
/** | |
* The entity ID of this SP. | |
* | |
* @var string | |
*/ | |
private $entityId; | |
/** | |
* The metadata of this SP. | |
* | |
* @var SimpleSAML_Configuration. | |
*/ | |
private $metadata; | |
/** | |
* The IdP the user is allowed to log into. | |
* | |
* @var string|NULL The IdP the user can log into, or NULL if the user can log into all IdPs. | |
*/ | |
private $idp; | |
/** | |
* URL to discovery service. | |
* | |
* @var string|NULL | |
*/ | |
private $discoURL; | |
/** | |
* Constructor for SAML SP authentication source. | |
* | |
* @param array $info Information about this authentication source. | |
* @param array $config Configuration. | |
*/ | |
public function __construct($info, $config) { | |
assert('is_array($info)'); | |
assert('is_array($config)'); | |
/* Call the parent constructor first, as required by the interface. */ | |
parent::__construct($info, $config); | |
if (!isset($config['entityID'])) { | |
$config['entityID'] = $this->getMetadataURL(); | |
} | |
/* For compatibility with code that assumes that $metadata->getString('entityid') gives the entity id. */ | |
$config['entityid'] = $config['entityID']; | |
$this->metadata = SimpleSAML_Configuration::loadFromArray($config, 'authsources[' . var_export($this->authId, TRUE) . ']'); | |
$this->entityId = $this->metadata->getString('entityID'); | |
$this->idp = $this->metadata->getString('idp', NULL); | |
$this->discoURL = $this->metadata->getString('discoURL', NULL); | |
if (empty($this->discoURL) && SimpleSAML_Module::isModuleEnabled('discojuice')) { | |
$this->discoURL = SimpleSAML_Module::getModuleURL('discojuice/central.php'); | |
} | |
} | |
/** | |
* Retrieve the URL to the metadata of this SP. | |
* | |
* @return string The metadata URL. | |
*/ | |
public function getMetadataURL() { | |
return SimpleSAML_Module::getModuleURL('saml/sp/metadata.php/' . urlencode($this->authId)); | |
} | |
/** | |
* Retrieve the entity id of this SP. | |
* | |
* @return string The entity id of this SP. | |
*/ | |
public function getEntityId() { | |
return $this->entityId; | |
} | |
/** | |
* Retrieve the metadata of this SP. | |
* | |
* @return SimpleSAML_Configuration The metadata of this SP. | |
*/ | |
public function getMetadata() { | |
return $this->metadata; | |
} | |
/** | |
* Retrieve the metadata of an IdP. | |
* | |
* @param string $entityId The entity id of the IdP. | |
* @return SimpleSAML_Configuration The metadata of the IdP. | |
*/ | |
public function getIdPMetadata($entityId) { | |
assert('is_string($entityId)'); | |
if ($this->idp !== NULL && $this->idp !== $entityId) { | |
throw new SimpleSAML_Error_Exception('Cannot retrieve metadata for IdP ' . var_export($entityId, TRUE) . | |
' because it isn\'t a valid IdP for this SP.'); | |
} | |
$metadataHandler = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); | |
/* First, look in saml20-idp-remote. */ | |
try { | |
return $metadataHandler->getMetaDataConfig($entityId, 'saml20-idp-remote'); | |
} catch (Exception $e) { | |
/* Metadata wasn't found. */ | |
} | |
/* Not found in saml20-idp-remote, look in shib13-idp-remote. */ | |
try { | |
return $metadataHandler->getMetaDataConfig($entityId, 'shib13-idp-remote'); | |
} catch (Exception $e) { | |
/* Metadata wasn't found. */ | |
} | |
/* Not found. */ | |
throw new SimpleSAML_Error_Exception('Could not find the metadata of an IdP with entity ID ' . var_export($entityId, TRUE)); | |
} | |
/** | |
* Send a SAML1 SSO request to an IdP. | |
* | |
* @param SimpleSAML_Configuration $idpMetadata The metadata of the IdP. | |
* @param array $state The state array for the current authentication. | |
*/ | |
private function startSSO1(SimpleSAML_Configuration $idpMetadata, array $state) { | |
$idpEntityId = $idpMetadata->getString('entityid'); | |
$state['saml:idp'] = $idpEntityId; | |
$ar = new SimpleSAML_XML_Shib13_AuthnRequest(); | |
$ar->setIssuer($this->entityId); | |
$id = SimpleSAML_Auth_State::saveState($state, 'saml:sp:sso'); | |
$ar->setRelayState($id); | |
$useArtifact = $idpMetadata->getBoolean('saml1.useartifact', NULL); | |
if ($useArtifact === NULL) { | |
$useArtifact = $this->metadata->getBoolean('saml1.useartifact', FALSE); | |
} | |
if ($useArtifact) { | |
$shire = SimpleSAML_Module::getModuleURL('saml/sp/saml1-acs.php/' . $this->authId . '/artifact'); | |
} else { | |
$shire = SimpleSAML_Module::getModuleURL('saml/sp/saml1-acs.php/' . $this->authId); | |
} | |
$url = $ar->createRedirect($idpEntityId, $shire); | |
SimpleSAML_Logger::debug('Starting SAML 1 SSO to ' . var_export($idpEntityId, TRUE) . | |
' from ' . var_export($this->entityId, TRUE) . '.'); | |
SimpleSAML_Utilities::redirect($url); | |
} | |
/** | |
* Send a SAML2 SSO request to an IdP. | |
* | |
* @param SimpleSAML_Configuration $idpMetadata The metadata of the IdP. | |
* @param array $state The state array for the current authentication. | |
*/ | |
private function startSSO2(SimpleSAML_Configuration $idpMetadata, array $state) { | |
if (isset($state['saml:ProxyCount']) && $state['saml:ProxyCount'] < 0) { | |
SimpleSAML_Auth_State::throwException($state, new SimpleSAML_Error_ProxyCountExceeded("ProxyCountExceeded")); | |
} | |
//I Added This try/catch block | |
try { | |
$ar = sspmod_saml_Message::buildAuthnRequest($this->metadata, $idpMetadata); | |
} catch (Exception $e) { | |
$RelayStateUrl = $state['SimpleSAML_Auth_Default.ReturnURL']; | |
$IdP =$idpMetadata->getString('SingleSignOnService'); | |
$qry = array('query' => 'RelayState=' . urlencode($RelayStateUrl)); | |
$redir = add_query_arg('RelayState', urlencode($RelayStateUrl), $IdP); | |
wp_redirect($redir); | |
} | |
$ar->setAssertionConsumerServiceURL(SimpleSAML_Module::getModuleURL('saml/sp/saml2-acs.php/' . $this->authId)); | |
if (isset($state['SimpleSAML_Auth_Default.ReturnURL'])) { | |
$ar->setRelayState($state['SimpleSAML_Auth_Default.ReturnURL']); | |
} | |
if (isset($state['saml:AuthnContextClassRef'])) { | |
$accr = SimpleSAML_Utilities::arrayize($state['saml:AuthnContextClassRef']); | |
$ar->setRequestedAuthnContext(array('AuthnContextClassRef' => $accr)); | |
} | |
if (isset($state['ForceAuthn'])) { | |
$ar->setForceAuthn((bool)$state['ForceAuthn']); | |
} | |
if (isset($state['isPassive'])) { | |
$ar->setIsPassive((bool)$state['isPassive']); | |
} | |
if (isset($state['saml:NameIDPolicy'])) { | |
if (is_string($state['saml:NameIDPolicy'])) { | |
$policy = array( | |
'Format' => (string)$state['saml:NameIDPolicy'], | |
'AllowCreate' => TRUE, | |
); | |
} elseif (is_array($state['saml:NameIDPolicy'])) { | |
$policy = $state['saml:NameIDPolicy']; | |
} else { | |
throw new SimpleSAML_Error_Exception('Invalid value of $state[\'saml:NameIDPolicy\'].'); | |
} | |
$ar->setNameIdPolicy($policy); | |
} | |
if (isset($state['saml:IDPList'])) { | |
$IDPList = $state['saml:IDPList']; | |
} else { | |
$IDPList = array(); | |
} | |
$ar->setIDPList(array_unique(array_merge($this->metadata->getArray('IDPList', array()), | |
$idpMetadata->getArray('IDPList', array()), | |
(array) $IDPList))); | |
if (isset($state['saml:ProxyCount']) && $state['saml:ProxyCount'] !== null) { | |
$ar->setProxyCount($state['saml:ProxyCount']); | |
} elseif ($idpMetadata->getInteger('ProxyCount', null) !== null) { | |
$ar->setProxyCount($idpMetadata->getInteger('ProxyCount', null)); | |
} elseif ($this->metadata->getInteger('ProxyCount', null) !== null) { | |
$ar->setProxyCount($this->metadata->getInteger('ProxyCount', null)); | |
} | |
$requesterID = array(); | |
if (isset($state['saml:RequesterID'])) { | |
$requesterID = $state['saml:RequesterID']; | |
} | |
if (isset($state['core:SP'])) { | |
$requesterID[] = $state['core:SP']; | |
} | |
$ar->setRequesterID($requesterID); | |
if (isset($state['saml:Extensions'])) { | |
$ar->setExtensions($state['saml:Extensions']); | |
} | |
$id = SimpleSAML_Auth_State::saveState($state, 'saml:sp:sso', TRUE); | |
$ar->setId($id); | |
SimpleSAML_Logger::debug('Sending SAML 2 AuthnRequest to ' . var_export($idpMetadata->getString('entityid'), TRUE)); | |
$b = new SAML2_HTTPRedirect(); | |
$this->sendSAML2AuthnRequest($state, $b, $ar); | |
assert('FALSE'); | |
} | |
/** | |
* Function to actually send the authentication request. | |
* | |
* This function does not return. | |
* | |
* @param array &$state The state array. | |
* @param SAML2_Binding $binding The binding. | |
* @param SAML2_AuthnRequest $ar The authentication request. | |
*/ | |
public function sendSAML2AuthnRequest(array &$state, SAML2_Binding $binding, SAML2_AuthnRequest $ar) { | |
$binding->send($ar); | |
assert('FALSE'); | |
} | |
/** | |
* Send a SSO request to an IdP. | |
* | |
* @param string $idp The entity ID of the IdP. | |
* @param array $state The state array for the current authentication. | |
*/ | |
public function startSSO($idp, array $state) { | |
assert('is_string($idp)'); | |
$idpMetadata = $this->getIdPMetadata($idp); | |
$type = $idpMetadata->getString('metadata-set'); | |
switch ($type) { | |
case 'shib13-idp-remote': | |
$this->startSSO1($idpMetadata, $state); | |
assert('FALSE'); /* Should not return. */ | |
case 'saml20-idp-remote': | |
$this->startSSO2($idpMetadata, $state); | |
assert('FALSE'); /* Should not return. */ | |
default: | |
/* Should only be one of the known types. */ | |
assert('FALSE'); | |
} | |
} | |
/** | |
* Start an IdP discovery service operation. | |
* | |
* @param array $state The state array. | |
*/ | |
private function startDisco(array $state) { | |
$id = SimpleSAML_Auth_State::saveState($state, 'saml:sp:sso'); | |
$config = SimpleSAML_Configuration::getInstance(); | |
$discoURL = $this->discoURL; | |
if ($discoURL === NULL) { | |
/* Fallback to internal discovery service. */ | |
$discoURL = SimpleSAML_Module::getModuleURL('saml/disco.php'); | |
} | |
$returnTo = SimpleSAML_Module::getModuleURL('saml/sp/discoresp.php', array('AuthID' => $id)); | |
$params = array( | |
'entityID' => $this->entityId, | |
'return' => $returnTo, | |
'returnIDParam' => 'idpentityid' | |
); | |
if(isset($state['saml:IDPList'])) { | |
$params['IDPList'] = $state['saml:IDPList']; | |
} | |
SimpleSAML_Utilities::redirect($discoURL, $params); | |
} | |
/** | |
* Start login. | |
* | |
* This function saves the information about the login, and redirects to the IdP. | |
* | |
* @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['saml:sp:AuthId'] = $this->authId; | |
$idp = $this->idp; | |
if (isset($state['saml:idp'])) { | |
$idp = (string)$state['saml:idp']; | |
} | |
if ($idp === NULL && isset($state['saml:IDPList']) && sizeof($state['saml:IDPList']) == 1) { | |
$idp = $state['saml:IDPList'][0]; | |
} | |
if ($idp === NULL) { | |
$this->startDisco($state); | |
assert('FALSE'); | |
} | |
$this->startSSO($idp, $state); | |
assert('FALSE'); | |
} | |
/** | |
* Start a SAML 2 logout operation. | |
* | |
* @param array $state The logout state. | |
*/ | |
public function startSLO2(&$state) { | |
assert('is_array($state)'); | |
assert('array_key_exists("saml:logout:IdP", $state)'); | |
assert('array_key_exists("saml:logout:NameID", $state)'); | |
assert('array_key_exists("saml:logout:SessionIndex", $state)'); | |
$id = SimpleSAML_Auth_State::saveState($state, 'saml:slosent'); | |
$idp = $state['saml:logout:IdP']; | |
$nameId = $state['saml:logout:NameID']; | |
$sessionIndex = $state['saml:logout:SessionIndex']; | |
$idpMetadata = $this->getIdPMetadata($idp); | |
$endpoint = $idpMetadata->getDefaultEndpoint('SingleLogoutService', array(SAML2_Const::BINDING_HTTP_REDIRECT), FALSE); | |
if ($endpoint === FALSE) { | |
SimpleSAML_Logger::info('No logout endpoint for IdP ' . var_export($idp, TRUE) . '.'); | |
return; | |
} | |
$lr = sspmod_saml_Message::buildLogoutRequest($this->metadata, $idpMetadata); | |
$lr->setNameId($nameId); | |
$lr->setSessionIndex($sessionIndex); | |
$lr->setRelayState($id); | |
$encryptNameId = $idpMetadata->getBoolean('nameid.encryption', NULL); | |
if ($encryptNameId === NULL) { | |
$encryptNameId = $this->metadata->getBoolean('nameid.encryption', FALSE); | |
} | |
if ($encryptNameId) { | |
$lr->encryptNameId(sspmod_saml_Message::getEncryptionKey($idpMetadata)); | |
} | |
$b = new SAML2_HTTPRedirect(); | |
$b->send($lr); | |
assert('FALSE'); | |
} | |
/** | |
* Start logout operation. | |
* | |
* @param array $state The logout state. | |
*/ | |
public function logout(&$state) { | |
assert('is_array($state)'); | |
assert('array_key_exists("saml:logout:Type", $state)'); | |
$logoutType = $state['saml:logout:Type']; | |
switch ($logoutType) { | |
case 'saml1': | |
/* Nothing to do. */ | |
return; | |
case 'saml2': | |
$this->startSLO2($state); | |
return; | |
default: | |
/* Should never happen. */ | |
assert('FALSE'); | |
} | |
} | |
/** | |
* Handle a response from a SSO operation. | |
* | |
* @param array $state The authentication state. | |
* @param string $idp The entity id of the IdP. | |
* @param array $attributes The attributes. | |
*/ | |
public function handleResponse(array $state, $idp, array $attributes) { | |
assert('is_string($idp)'); | |
assert('array_key_exists("LogoutState", $state)'); | |
assert('array_key_exists("saml:logout:Type", $state["LogoutState"])'); | |
$idpMetadata = $this->getIdpMetadata($idp); | |
$spMetadataArray = $this->metadata->toArray(); | |
$idpMetadataArray = $idpMetadata->toArray(); | |
$authProcState = array( | |
'saml:sp:IdP' => $idp, | |
'saml:sp:State' => $state, | |
'ReturnCall' => array('sspmod_saml_Auth_Source_SP', 'onProcessingCompleted'), | |
'Attributes' => $attributes, | |
'Destination' => $spMetadataArray, | |
'Source' => $idpMetadataArray, | |
); | |
if (isset($state['saml:sp:NameID'])) { | |
$authProcState['saml:sp:NameID'] = $state['saml:sp:NameID']; | |
} | |
if (isset($state['saml:sp:SessionIndex'])) { | |
$authProcState['saml:sp:SessionIndex'] = $state['saml:sp:SessionIndex']; | |
} | |
$pc = new SimpleSAML_Auth_ProcessingChain($idpMetadataArray, $spMetadataArray, 'sp'); | |
$pc->processState($authProcState); | |
self::onProcessingCompleted($authProcState); | |
} | |
/** | |
* Handle a logout request from an IdP. | |
* | |
* @param string $idpEntityId The entity ID of the IdP. | |
*/ | |
public function handleLogout($idpEntityId) { | |
assert('is_string($idpEntityId)'); | |
/* Call the logout callback we registered in onProcessingCompleted(). */ | |
$this->callLogoutCallback($idpEntityId); | |
} | |
/** | |
* Called when we have completed the procssing chain. | |
* | |
* @param array $authProcState The processing chain state. | |
*/ | |
public static function onProcessingCompleted(array $authProcState) { | |
assert('array_key_exists("saml:sp:IdP", $authProcState)'); | |
assert('array_key_exists("saml:sp:State", $authProcState)'); | |
assert('array_key_exists("Attributes", $authProcState)'); | |
$idp = $authProcState['saml:sp:IdP']; | |
$state = $authProcState['saml:sp:State']; | |
$sourceId = $state['saml:sp:AuthId']; | |
$source = SimpleSAML_Auth_Source::getById($sourceId); | |
if ($source === NULL) { | |
throw new Exception('Could not find authentication source with id ' . $sourceId); | |
} | |
/* Register a callback that we can call if we receive a logout request from the IdP. */ | |
$source->addLogoutCallback($idp, $state); | |
$state['Attributes'] = $authProcState['Attributes']; | |
if (isset($state['saml:sp:isUnsolicited']) && (bool)$state['saml:sp:isUnsolicited']) { | |
if (!empty($state['saml:sp:RelayState'])) { | |
$redirectTo = $state['saml:sp:RelayState']; | |
} else { | |
$redirectTo = $source->getMetadata()->getString('RelayState', '/'); | |
} | |
SimpleSAML_Auth_Default::handleUnsolicitedAuth($sourceId, $state, $redirectTo); | |
} | |
SimpleSAML_Auth_Source::completeAuth($state); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment