diff --git a/app/config/config.yml b/app/config/config.yml index 5079db3c20..d2859b13e8 100644 --- a/app/config/config.yml +++ b/app/config/config.yml @@ -27,6 +27,7 @@ open_conext_engine_block: eb.enable_sso_notification: "%feature_enable_sso_notification%" eb.feature_enable_consent: "%feature_enable_consent%" eb.enable_sso_session_cookie: "%feature_enable_sso_session_cookie%" + eb.feature_enable_idp_initiated_flow: "%feature_enable_idp_initiated_flow%" eb.stepup.sfo.override_engine_entityid: "%feature_stepup_sfo_override_engine_entityid%" diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist index b69d9cad68..b5631b4ad9 100644 --- a/app/config/parameters.yml.dist +++ b/app/config/parameters.yml.dist @@ -224,6 +224,7 @@ parameters: feature_block_user_on_violation: false feature_enable_consent: true feature_stepup_sfo_override_engine_entityid: false + feature_enable_idp_initiated_flow: true ########################################################################################## ## PROFILE SETTINGS diff --git a/src/OpenConext/EngineBlockBundle/Configuration/TestFeatureConfiguration.php b/src/OpenConext/EngineBlockBundle/Configuration/TestFeatureConfiguration.php index 7d4167991c..4a13a5a00e 100644 --- a/src/OpenConext/EngineBlockBundle/Configuration/TestFeatureConfiguration.php +++ b/src/OpenConext/EngineBlockBundle/Configuration/TestFeatureConfiguration.php @@ -46,6 +46,7 @@ public function __construct() $this->setFeature(new Feature('eb.feature_enable_consent', true)); $this->setFeature(new Feature('eb.enable_sso_session_cookie', true)); $this->setFeature(new Feature('eb.stepup.sfo.override_engine_entityid', false)); + $this->setFeature(new Feature('eb.feature_enable_idp_initiated_flow', true)); } public function setFeature(Feature $feature): void diff --git a/src/OpenConext/EngineBlockBundle/Controller/IdentityProviderController.php b/src/OpenConext/EngineBlockBundle/Controller/IdentityProviderController.php index 386044ca7f..5ca07895e4 100644 --- a/src/OpenConext/EngineBlockBundle/Controller/IdentityProviderController.php +++ b/src/OpenConext/EngineBlockBundle/Controller/IdentityProviderController.php @@ -24,9 +24,11 @@ use OpenConext\EngineBlock\Service\RequestAccessMailer; use OpenConext\EngineBlock\Validator\RequestValidator; use OpenConext\EngineBlockBridge\ResponseFactory; +use OpenConext\EngineBlockBundle\Configuration\FeatureConfigurationInterface; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Twig_Environment; /** @@ -74,6 +76,11 @@ class IdentityProviderController implements AuthenticationLoopThrottlingControll */ private $bindingValidator; + /** + * @var FeatureConfigurationInterface + */ + private $featureConfiguration; + public function __construct( EngineBlock_ApplicationSingleton $engineBlockApplicationSingleton, Twig_Environment $twig, @@ -82,7 +89,8 @@ public function __construct( RequestValidator $requestValidator, RequestValidator $bindingValidator, RequestValidator $unsolicitedRequestValidator, - AuthenticationStateHelperInterface $authenticationStateHelper + AuthenticationStateHelperInterface $authenticationStateHelper, + FeatureConfigurationInterface $featureConfiguration ) { $this->engineBlockApplicationSingleton = $engineBlockApplicationSingleton; $this->twig = $twig; @@ -92,6 +100,7 @@ public function __construct( $this->bindingValidator = $bindingValidator; $this->unsolicitedRequestValidator = $unsolicitedRequestValidator; $this->authenticationStateHelper = $authenticationStateHelper; + $this->featureConfiguration = $featureConfiguration; } /** @@ -130,9 +139,14 @@ public function singleSignOnAction(Request $request, $keyId = null, $idpHash = n * @param null|string $keyId * @param null|string $idpHash * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response + * @throws NotFoundHttpException If the IdP-initiated flow has been disabled by config */ public function unsolicitedSingleSignOnAction(Request $request, $keyId = null, $idpHash = null) { + if (!$this->featureConfiguration->isEnabled('eb.feature_enable_idp_initiated_flow')) { + throw new NotFoundHttpException(); + } + $this->unsolicitedRequestValidator->isValid($request); $cortoAdapter = new EngineBlock_Corto_Adapter(); diff --git a/src/OpenConext/EngineBlockBundle/Resources/config/controllers/authentication.yml b/src/OpenConext/EngineBlockBundle/Resources/config/controllers/authentication.yml index 7daedb2c4a..c4379fb05a 100644 --- a/src/OpenConext/EngineBlockBundle/Resources/config/controllers/authentication.yml +++ b/src/OpenConext/EngineBlockBundle/Resources/config/controllers/authentication.yml @@ -22,6 +22,7 @@ services: - "@engineblock.validator.saml_binding_validator" - "@engineblock.validator.unsolicited_sso_request_validator" - "@engineblock.service.authentication_state_helper" + - "@engineblock.features" engineblock.controller.authentication.index: class: OpenConext\EngineBlockBundle\Controller\IndexController diff --git a/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Consent.feature b/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Consent.feature index ea31d0eb6d..ff6e02c9ac 100644 --- a/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Consent.feature +++ b/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Consent.feature @@ -80,13 +80,6 @@ Feature: And the response should contain "Motivation for affiliation" And the response should contain "Motivation for orcid" - Scenario: The user is presented with an institution provided consent text - Given I log in at "Dummy-SP" - And the IdP "Dummy-IdP" provides a consent message "Institutional privacy message" for SP "Dummy-SP" - And I pass through EngineBlock - And I pass through the IdP - Then the response should contain "Institutional privacy message" - Scenario: The user can reload the consent screen without error Given I log in at "Dummy-SP" And I pass through EngineBlock @@ -95,6 +88,13 @@ Feature: When I reload the page Then the response should contain "Proceed to Dummy-SP" + Scenario: The user is presented with an institution provided consent text + Given I log in at "Dummy-SP" + And the IdP "Dummy-IdP" provides a consent message "Institutional privacy message" for SP "Dummy-SP" + And I pass through EngineBlock + And I pass through the IdP + Then the response should contain "Institutional privacy message" + Scenario: The user sees the identifier section when nameid is persistent Given SP "Dummy-SP" uses the Persistent NameID format And I log in at "Dummy-SP" diff --git a/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/UnsolicitedSingleSignOnDisabled.feature b/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/UnsolicitedSingleSignOnDisabled.feature new file mode 100644 index 0000000000..0f86bb2b32 --- /dev/null +++ b/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/UnsolicitedSingleSignOnDisabled.feature @@ -0,0 +1,18 @@ +Feature: + In order to disable unsolicited single sign On + As an administrator + I want to be able to disable unsolicited login + + Background: + Given an EngineBlock instance on "vm.openconext.org" + And feature "eb.feature_enable_idp_initiated_flow" is disabled + And no registered SPs + And no registered Idps + And an Identity Provider named "Dummy IdP" + And a Service Provider named "Dummy SP" + + # The feature flag: eb.feature_enable_idp_initiated_flow can disable unsolicited login + # EB Shows a 404 page in that case as the entire HTTP route is blocked in that case + Scenario: Engine disallows unsolicited login + When An IdP initiated Single Sign on for SP "Dummy SP" is triggered by IdP "Dummy IdP" + Then I should see "404 - Page not found" diff --git a/src/OpenConext/EngineBlockFunctionalTestingBundle/Resources/config/controllers.yml b/src/OpenConext/EngineBlockFunctionalTestingBundle/Resources/config/controllers.yml index f100e9bbf3..109fbf9650 100644 --- a/src/OpenConext/EngineBlockFunctionalTestingBundle/Resources/config/controllers.yml +++ b/src/OpenConext/EngineBlockFunctionalTestingBundle/Resources/config/controllers.yml @@ -33,3 +33,16 @@ services: arguments: - "@engineblock.mock_clients.mock_stepup_gateway" - "@twig" + + engineblock.controller.authentication.identity_provider: + class: OpenConext\EngineBlockBundle\Controller\IdentityProviderController + arguments: + - "@engineblock.compat.application" + - "@twig" + - "@engineblock.compat.logger" + - "@engineblock.service.request_access_mailer" + - "@engineblock.validator.sso_request_validator" + - "@engineblock.validator.saml_binding_validator" + - "@engineblock.validator.unsolicited_sso_request_validator" + - "@engineblock.service.authentication_state_helper" + - "@engineblock.functional_testing.fixture.features"