Skip to content

Commit

Permalink
Store SSO cookie only when authn was a success
Browse files Browse the repository at this point in the history
When the user would cancel the authentication, the response rendering
service would still write the SSO cookie. Handing out SSO without an
actual successful authentication taken place

This was issue was fixed in the three scenarios where a SSO cookie can
be created.

1. On the regular gateway authentication
2. On the second factor only respond action
3. When the response is an ADFS response

https://www.pivotaltracker.com/story/show/186951513
  • Loading branch information
MKodde committed Feb 6, 2024
1 parent c38a614 commit 99d1220
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,9 @@ public function renderSamlResponse(
$httpResponse = $this->render($view, $parameters);

$ssoCookieService = $this->get('gateway.service.sso_2fa_cookie');
$ssoCookieService->handleSsoOn2faCookieStorage($responseContext, $request, $httpResponse);
if ($response->isSuccess()) {
$ssoCookieService->handleSsoOn2faCookieStorage($responseContext, $request, $httpResponse);
}
return $httpResponse;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ private function renderSamlResponse(
)
);

$this->ssoCookieService->handleSsoOn2faCookieStorage($context, $request, $httpResponse);
if ($response->isSuccess()) {
$this->ssoCookieService->handleSsoOn2faCookieStorage($context, $request, $httpResponse);
}
return $httpResponse;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,10 @@ public function respondAction(Request $request)
$httpResponse = $responseRendering->renderResponse($responseContext, $response, $request);
}

$ssoCookieService = $this->get('gateway.service.sso_2fa_cookie');
$ssoCookieService->handleSsoOn2faCookieStorage($responseContext, $request, $httpResponse);

if ($response->isSuccess()) {
$ssoCookieService = $this->get('gateway.service.sso_2fa_cookie');
$ssoCookieService->handleSsoOn2faCookieStorage($responseContext, $request, $httpResponse);
}
// We can now forget the selected second factor.
$responseContext->finalizeAuthentication();

Expand Down
18 changes: 18 additions & 0 deletions tests/features/bootstrap/FeatureContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
use Behat\Behat\Hook\Scope\BeforeFeatureScope;
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
use Behat\Mink\Exception\ExpectationException;
use Exception;
use RuntimeException;
use Surfnet\StepupGateway\Behat\Service\FixtureService;
use function is_null;
use function sprintf;

class FeatureContext implements Context
Expand Down Expand Up @@ -279,6 +281,22 @@ public function theResponseShouldHaveASSO2FACookie()
$this->validateSsoOn2faCookie($cookieValue);
}

/**
* @Then /^the response should not have a SSO\-2FA cookie$/
* @throws ExpectationException
*/
public function theResponseShouldNotHaveASSO2FACookie()
{
$this->minkContext->visit('https://gateway.stepup.example.com/info');
$cookie = $this->minkContext->getSession()->getCookie($this->sso2faCookieName);
if (!is_null($cookie)) {
throw new ExpectationException(
'The SSO cookie must NOT be present',
$this->minkContext->getSession()->getDriver()
);
}
}

/**
* @Then /^a new SSO\-2FA cookie was written$/
* @throws ExpectationException
Expand Down
28 changes: 28 additions & 0 deletions tests/features/sso-on-2fa.feature
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,34 @@ Feature: As an institution that uses the SSO on Second Factor authentication
And the response should have a SSO-2FA cookie
And the SSO-2FA cookie should contain "urn:collab:person:stepup.example.com:user-1"

Scenario: Cancelling out of an authentication should not yield a SSO cookie
Given a user from "stepup.example.com" identified by "urn:collab:person:stepup.example.com:jane-1" with a vetted "Yubikey" token
When urn:collab:person:stepup.example.com:jane-1 starts an authentication requiring LoA 2
And I authenticate at the IdP as jane-1
Then I should see the Yubikey OTP screen
When I cancel the authentication
And I pass through the Gateway
And the response should not have a SSO-2FA cookie

Scenario: Cancelling an authentication yields an ADFS proof SAML AuthnFailed Response
Given a user from "stepup.example.com" identified by "urn:collab:person:stepup.example.com:eric_lilliebridge" with a vetted "Yubikey" token
When urn:collab:person:stepup.example.com:eric_lilliebridge starts an ADFS authentication requiring http://stepup.example.com/assurance/sfo-level3
Then I should see the Yubikey OTP screen
When I cancel the authentication
And I pass through the Gateway
Then the ADFS response should carry the ADFS POST parameters
And the ADFS response should match xpath '//samlp:StatusCode[@Value="urn:oasis:names:tc:SAML:2.0:status:AuthnFailed"]'
And the response should contain 'Authentication cancelled by user'
And the response should not have a SSO-2FA cookie

Scenario: Cancelling out of an SFO authentication should not yield a SSO cookie
Given a user from "stepup.example.com" identified by "urn:collab:person:stepup.example.com:joe-3" with a vetted "SMS" token
When urn:collab:person:stepup.example.com:joe-3 starts an SFO authentication
Then I should see the SMS verification screen
When I cancel the authentication
And I pass through the Gateway
And the response should not have a SSO-2FA cookie

Scenario: A successive authentication skips the Yubikey second factor authentication
Given a user from "stepup.example.com" identified by "urn:collab:person:stepup.example.com:user-2" with a vetted "Yubikey" token
When urn:collab:person:stepup.example.com:user-2 starts an authentication requiring LoA 2
Expand Down

0 comments on commit 99d1220

Please sign in to comment.