fix IDP-initiated Logout #334

Signed-off-by: Dylann Cordel <d.cordel@webu.coop>
This commit is contained in:
Dylann Cordel 2019-06-07 19:00:08 +02:00 committed by John Molakvoæ (skjnldsv)
parent 83ca392971
commit f780006005
No known key found for this signature in database
GPG key ID: 60C25B8C072916CF

View file

@ -309,6 +309,7 @@ class SAMLController extends Controller {
} }
/** /**
* @PublicPage
* @NoAdminRequired * @NoAdminRequired
* @NoCSRFRequired * @NoCSRFRequired
* *
@ -316,25 +317,43 @@ class SAMLController extends Controller {
* @throws Error * @throws Error
*/ */
public function singleLogoutService() { public function singleLogoutService() {
$isFromGS = ($this->config->getSystemValue('gs.enabled', false) &&
$this->config->getSystemValue('gss.mode', '') === 'master');
$isFromIDP = !$isFromGS && !empty($_GET['SAMLRequest']);
$pass = $this->request->passesCSRFCheck(); if($isFromIDP) {
$isGlobalScaleEnabled = $this->config->getSystemValue('gs.enabled', false); // requests comes from the IDP so let it manage the logout
$gssMode = $this->config->getSystemValue('gss.mode', ''); // (or raise Error if request is invalid)
if (!$pass && $isGlobalScaleEnabled && $gssMode === 'master') { $pass = True ;
} elseif($isFromGS) {
// Request is from master GlobalScale
// Request validity is check via a JSON Web Token
$jwt = $this->request->getParam('jwt', ''); $jwt = $this->request->getParam('jwt', '');
$pass = $this->isValidJwt($jwt); $pass = $this->isValidJwt($jwt);
} else {
// standard request : need read CRSF check
$pass = $this->request->passesCSRFCheck();
} }
if($pass) { if($pass) {
$idp = $this->session->get('user_saml.Idp'); $idp = $this->session->get('user_saml.Idp');
$auth = new Auth($this->SAMLSettings->getOneLoginSettingsArray($idp)); $auth = new Auth($this->SAMLSettings->getOneLoginSettingsArray($idp));
$returnTo = null; $stay = true ; // $auth will return the redirect URL but won't perform the redirect himself
$parameters = array(); if($isFromIDP){
$nameId = $this->session->get('user_saml.samlNameId'); $keepLocalSession = true ; // do not let processSLO to delete the entire session. Let userSession->logout do the job
$sessionIndex = $this->session->get('user_saml.samlSessionIndex'); $targetUrl = $auth->processSLO($keepLocalSession, null, false, null, $stay);
$this->userSession->logout(); } else {
$targetUrl = $auth->logout($returnTo, $parameters, $nameId, $sessionIndex, true); // If request is not from IDP, we must send him the logout request
} else { $parameters = array();
$nameId = $this->session->get('user_saml.samlNameId');
$sessionIndex = $this->session->get('user_saml.samlSessionIndex');
$targetUrl = $auth->logout(null, [], $nameId, $sessionIndex, $stay);
}
if(!empty($targetUrl) && !$auth->getLastErrorReason()){
$this->userSession->logout();
}
}
if(empty($targetUrl)){
$targetUrl = $this->urlGenerator->getAbsoluteURL('/'); $targetUrl = $this->urlGenerator->getAbsoluteURL('/');
} }