Skip to content

Commit 3767e04

Browse files
committed
Start POC to test GSSP bypass flow
1 parent 1c2b058 commit 3767e04

File tree

5 files changed

+70
-9
lines changed

5 files changed

+70
-9
lines changed

config/openconext/parameters.yaml.dist

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,14 @@ parameters:
180180
#
181181
# Example value: 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
182182
sso_encryption_key: 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
183+
184+
# The GSSP ID from samlstepupproviders.yaml to use as fallback GSSP
185+
# Set fallback_gssp to false to disable the fallback_gssp functionality
186+
# fallback_gssp: false
187+
fallback_gssp: 'azuremfa'
188+
189+
# The user attribute to use in the Subject of the AuthnRequest to the fallback GSSP
190+
fallback_gssp_subject_attribute: 'urn:mace:dir:attribute-def:mail'
191+
192+
# The user attribute to use to determine the user's home institution
193+
fallback_gssp_institution_attribute: 'urn:mace:terena.org:attribute-def:schacHomeOrganization'

src/Surfnet/StepupGateway/GatewayBundle/Controller/SecondFactorController.php

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,19 @@ public function selectSecondFactorForVerification(
158158
// todo: handle sso registration bypass.
159159
if ($authenticationMode === self::MODE_SFO) {
160160
// - the user does not have an active token
161-
// - a LoA1.5 (i.e. self asserted) authentication is requested
162161

162+
// - a LoA1.5 (i.e. self asserted) authentication is requested
163163
// - a fallback GSSP is configured
164164
// - this "fallback" option is enabled for the institution that the user belongs to.
165-
166165
// - the configured user attribute is present in the AuthnRequest
167166
// - handle authentication by forwarding it to a designated GSSP using the GSSP protocol instead of returning an error.
167+
168+
// var_dump($requiredLoa);
169+
// die();
170+
171+
$secondFactor = SecondFactor::create('gssp_fallback', 'azuremfa', '');
172+
return $this->selectAndRedirectTo($secondFactor, $context, $authenticationMode);
173+
168174
}
169175

170176
return $this->forward(
@@ -351,6 +357,23 @@ public function verifyGssf(Request $request): Response
351357
/** @var SecondFactorService $secondFactorService */
352358
$secondFactorService = $this->get('gateway.service.second_factor_service');
353359
/** @var SecondFactor $secondFactor */
360+
361+
if ($selectedSecondFactor === 'gssp_fallback') {
362+
// Also send the response context service id, as later we need to know if this is regular SSO or SFO authn.
363+
$responseContextServiceId = $context->getResponseContextServiceId();
364+
365+
return $this->forward(
366+
SamlProxyController::class . '::sendSecondFactorVerificationAuthnRequest',
367+
[
368+
'provider' => 'azuremfa',
369+
'subjectNameId' => '[email protected]',
370+
'responseContextServiceId' => $responseContextServiceId,
371+
'relayState' => $context->getRelayState(),
372+
],
373+
);
374+
375+
}
376+
354377
$secondFactor = $secondFactorService->findByUuid($selectedSecondFactor);
355378
if (!$secondFactor) {
356379
throw new RuntimeException(
@@ -389,7 +412,19 @@ public function gssfVerified(Request $request): Response
389412

390413
$selectedSecondFactor = $this->getSelectedSecondFactor($context, $logger);
391414

392-
/** @var SecondFactor $secondFactor */
415+
if ($selectedSecondFactor === 'gssp_fallback') {
416+
// $this->getAuthenticationLogger()->logSecondFactorAuthentication($originalRequestId, $authenticationMode);
417+
$context->markSecondFactorVerified();
418+
419+
$logger->info(sprintf(
420+
'Marked GSSF "%s" as verified, forwarding to Gateway controller to respond',
421+
$selectedSecondFactor,
422+
));
423+
424+
return $this->forward($context->getResponseAction());
425+
}
426+
427+
/** @var SecondFactor $secondFactor */
393428
$secondFactor = $this->get('gateway.service.second_factor_service')->findByUuid($selectedSecondFactor);
394429
if (!$secondFactor) {
395430
throw new RuntimeException(

src/Surfnet/StepupGateway/GatewayBundle/Entity/SecondFactor.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,15 @@ final private function __construct()
118118
{
119119
}
120120

121+
public static function create(string $id, string $type, string $displayLocale)
122+
{
123+
$sf = new self();
124+
$sf->secondFactorId = $id;
125+
$sf->secondFactorType = $type;
126+
$sf->displayLocale = $displayLocale;
127+
return $sf;
128+
}
129+
121130
public function canSatisfy(Loa $loa, SecondFactorTypeService $service): bool
122131
{
123132
$secondFactorType = new SecondFactorType($this->secondFactorType);

src/Surfnet/StepupGateway/SecondFactorOnlyBundle/Service/Gateway/RespondService.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,17 @@ public function respond(ResponseContext $responseContext, Request $request)
101101
);
102102
}
103103

104-
$secondFactor = $this->secondFactorService->findByUuid($selectedSecondFactorUuid);
105-
$this->responseValidator->validate($request, $secondFactor, $responseContext->getIdentityNameId());
104+
105+
$loaLevel = 1.5;
106+
if ($selectedSecondFactorUuid !== 'gssp_fallback') {
107+
$secondFactor = $this->secondFactorService->findByUuid($selectedSecondFactorUuid);
108+
$this->responseValidator->validate($request, $secondFactor, $responseContext->getIdentityNameId());
109+
110+
$loaLevel = $secondFactor->getLoaLevel($this->secondFactorTypeService);
111+
}
106112

107113
$grantedLoa = $this->loaResolutionService
108-
->getLoaByLevel($secondFactor->getLoaLevel($this->secondFactorTypeService));
114+
->getLoaByLevel($loaLevel);
109115

110116
$authnContextClassRef = $this->loaAliasLookupService->findAliasByLoa($grantedLoa);
111117

tests/features/sfo-registration-bypass.feature

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
#@functional
2-
Feature: As an institution that uses the second factor only feature
1+
@functional
2+
Feature: As an institution that uses the registration bypass feature
33
In order to do second factor authentications
4-
I must be able to successfully authenticate with my second factor tokens
4+
I must be able to successfully authenticate with my second factor tokens without prior registration
55

66
Scenario: A Yubikey SFO authentication
77
Given an SFO enabled SP with EntityID https://ssp.dev.openconext.local/module.php/saml/sp/metadata.php/second-sp

0 commit comments

Comments
 (0)