Skip to content

Commit

Permalink
Merge pull request #93 from samlev/logoutCallback
Browse files Browse the repository at this point in the history
Added 'delete session' callback option
  • Loading branch information
pitbulk committed Sep 9, 2015
2 parents b1f7fbe + 3c2ea26 commit 9f3583c
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 5 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,20 @@ if (!OneLogin_Saml2_LogoutRequest::isValid($this->_settings, $request)) {
}
```

If you aren't using the default PHP session, or otherwise need a manual
way to destroy the session, you can pass a callback method to the
`processSLO` method as the fourth parameter

```php
$keepLocalSession = False;
$callback = function () {
// Destroy user session
};

$auth->processSLO($keepLocalSession, null, false, $callback);
```


If we don't want that `processSLO` to destroy the session, pass a true
parameter to the `processSLO` method

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "onelogin/php-saml",
"description": "OneLogin PHP SAML Toolkit",
"license": "MIT",
"version": "2.6.0",
"version": "2.6.1",
"homepage": "https://onelogin.zendesk.com/hc/en-us/sections/200245634-SAML-Toolkits",
"keywords": ["saml", "saml2", "onelogin"],
"autoload": {
Expand Down
20 changes: 16 additions & 4 deletions lib/Saml2/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,13 @@ public function processResponse($requestId = null)
* Process the SAML Logout Response / Logout Request sent by the IdP.
*
* @param boolean $keepLocalSession When false will destroy the local session, otherwise will keep it
* @param string $requestId The ID of the LogoutRequest sent by this SP to the IdP
* @param string $requestId The ID of the LogoutRequest sent by this SP to the IdP
* @param bool $retrieveParametersFromServer
* @param callable $cbDeleteSession
* @return string|void
* @throws \OneLogin_Saml2_Error
*/
public function processSLO($keepLocalSession = false, $requestId = null, $retrieveParametersFromServer = false)
public function processSLO($keepLocalSession = false, $requestId = null, $retrieveParametersFromServer = false, $cbDeleteSession = null)
{
$this->_errors = array();
if (isset($_GET) && isset($_GET['SAMLResponse'])) {
Expand All @@ -148,7 +152,11 @@ public function processSLO($keepLocalSession = false, $requestId = null, $retrie
$this->_errors[] = 'logout_not_success';
} else {
if (!$keepLocalSession) {
OneLogin_Saml2_Utils::deleteLocalSession();
if ($cbDeleteSession === null) {
OneLogin_Saml2_Utils::deleteLocalSession();
} else {
call_user_func($cbDeleteSession);
}
}
}
} else if (isset($_GET) && isset($_GET['SAMLRequest'])) {
Expand All @@ -158,7 +166,11 @@ public function processSLO($keepLocalSession = false, $requestId = null, $retrie
$this->_errorReason = $logoutRequest->getError();
} else {
if (!$keepLocalSession) {
OneLogin_Saml2_Utils::deleteLocalSession();
if ($cbDeleteSession === null) {
OneLogin_Saml2_Utils::deleteLocalSession();
} else {
call_user_func($cbDeleteSession);
}
}
$inResponseTo = $logoutRequest->id;
$responseBuilder = new OneLogin_Saml2_LogoutResponse($this->_settings);
Expand Down
86 changes: 86 additions & 0 deletions tests/src/OneLogin/Saml2/AuthTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,42 @@ public function testProcessSLOResponseValidDeletingSession()
$this->assertFalse(isset($_SESSION['samltest']));
}

/**
* Tests the processSLO method of the OneLogin_Saml2_Auth class
* Case Valid Logout Response, validating deleting the local session
*
* @covers OneLogin_Saml2_Auth::processSLO
*/
public function testProcessSLOResponseValidDeletingSessionCallback()
{
$message = file_get_contents(TEST_ROOT . '/data/logout_responses/logout_response_deflated.xml.base64');

if (!isset($_SESSION)) {
$_SESSION = array();
}
$_SESSION['samltest'] = true;

$callback = function() {
$_SESSION['samltest'] = false;
};

// In order to avoid the destination problem
$plainMessage = gzinflate(base64_decode($message));
$currentURL = OneLogin_Saml2_Utils::getSelfURLNoQuery();
$plainMessage = str_replace('http://stuff.com/endpoints/endpoints/sls.php', $currentURL, $plainMessage);
$message = base64_encode(gzdeflate($plainMessage));

$_GET['SAMLResponse'] = $message;

$this->_auth->setStrict(true);
$this->_auth->processSLO(false, null, false, $callback);

$this->assertEmpty($this->_auth->getErrors());

$this->assertTrue(isset($_SESSION['samltest']));
$this->assertFalse($_SESSION['samltest']);
}

/**
* Tests the processSLO method of the OneLogin_Saml2_Auth class
* Case Invalid Logout Request
Expand Down Expand Up @@ -531,6 +567,56 @@ public function testProcessSLORequestDeletingSession()
}
}

/**
* Tests the processSLO method of the OneLogin_Saml2_Auth class
* Case Valid Logout Request, validating that the local session is deleted with callback,
* a LogoutResponse is created and a redirection executed
*
* @covers OneLogin_Saml2_Auth::processSLO
*/
public function testProcessSLORequestDeletingSessionCallback()
{
$message = file_get_contents(TEST_ROOT . '/data/logout_requests/logout_request_deflated.xml.base64');

// In order to avoid the destination problem
$plainMessage = gzinflate(base64_decode($message));
$currentURL = OneLogin_Saml2_Utils::getSelfURLNoQuery();
$plainMessage = str_replace('http://stuff.com/endpoints/endpoints/sls.php', $currentURL, $plainMessage);
$message = base64_encode(gzdeflate($plainMessage));

$_GET['SAMLRequest'] = $message;

if (!isset($_SESSION)) {
$_SESSION = array();
}
$_SESSION['samltest'] = true;

$callback = function() {
$_SESSION['samltest'] = false;
};

try {
$this->_auth->setStrict(true);
$this->_auth->processSLO(false, null, false, $callback);
$this->assertFalse(true);
} catch (Exception $e) {
$this->assertContains('Cannot modify header information', $e->getMessage());
$trace = $e->getTrace();
$targetUrl = getUrlFromRedirect($trace);
$parsedQuery = getParamsFromUrl($targetUrl);

$sloUrl = $this->_settingsInfo['idp']['singleLogoutService']['url'];
$this->assertContains($sloUrl, $targetUrl);
$this->assertArrayHasKey('SAMLResponse', $parsedQuery);
$this->assertArrayNotHasKey('RelayState', $parsedQuery);

// Session is alive
$this->assertTrue(isset($_SESSION['samltest']));
// But has been modified
$this->assertFalse(isset($_SESSION['samltest']));
}
}

/**
* Tests the processSLO method of the OneLogin_Saml2_Auth class
* Case Valid Logout Request, validating the relayState,
Expand Down

0 comments on commit 9f3583c

Please sign in to comment.