From 21cd0b3894b1695a2b155e7a26442d3b03c89ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Ivan=C4=8Di=C4=87?= Date: Fri, 7 Jun 2024 23:30:16 +0200 Subject: [PATCH] Make authorization endpoint available as Symfony route --- composer.json | 1 + .../conformance-back-channel-logout-ci.json | 48 +++++----- conformance-tests/conformance-basic-ci.json | 48 +++++----- .../conformance-implicit-ci.json | 48 +++++----- .../conformance-rp-initiated-logout-ci.json | 48 +++++----- docker/conformance.sql | 16 ++-- routing/routes/routes.php | 11 +++ routing/services/services.yml | 45 +++++++++- src/Bridges/PsrHttpBridge.php | 62 +++++++++++++ src/Codebooks/RoutesEnum.php | 1 + src/Controller/AuthorizationController.php | 35 +++++++- src/Factories/AuthorizationServerFactory.php | 17 ++-- src/Factories/Grant/AuthCodeGrantFactory.php | 9 +- src/Factories/Grant/ImplicitGrantFactory.php | 6 +- .../Grant/OAuth2ImplicitGrantFactory.php | 6 +- .../Grant/RefreshTokenGrantFactory.php | 6 +- src/Factories/IdTokenResponseFactory.php | 5 +- src/Factories/RequestRulesManagerFactory.php | 87 +++++++++++++++++++ src/ModuleConfig.php | 30 +++++++ src/Services/Container.php | 63 +++++++++----- src/Services/ErrorResponder.php | 48 ++++++++++ src/Services/OpMetadataService.php | 3 +- .../AuthorizationControllerTest.php | 23 +++++ tests/src/Services/OpMetadataServiceTest.php | 5 +- 24 files changed, 513 insertions(+), 158 deletions(-) create mode 100644 src/Bridges/PsrHttpBridge.php create mode 100644 src/Factories/RequestRulesManagerFactory.php create mode 100644 src/Services/ErrorResponder.php diff --git a/composer.json b/composer.json index 788debc0..70936b32 100644 --- a/composer.json +++ b/composer.json @@ -33,6 +33,7 @@ "simplesamlphp/composer-module-installer": "^1.3", "spomky-labs/base64url": "^2.0", "symfony/expression-language": "^6.3", + "symfony/psr-http-message-bridge": "^7.1", "web-token/jwt-framework": "^3" }, "require-dev": { diff --git a/conformance-tests/conformance-back-channel-logout-ci.json b/conformance-tests/conformance-back-channel-logout-ci.json index 544ca590..d5b0b08d 100644 --- a/conformance-tests/conformance-back-channel-logout-ci.json +++ b/conformance-tests/conformance-back-channel-logout-ci.json @@ -10,7 +10,7 @@ }, "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -79,7 +79,7 @@ "browser": [ { "comment": "updates placeholder during the second authorization", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -132,7 +132,7 @@ "browser": [ { "comment": "updates placeholder during the second authorization", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -185,11 +185,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -209,11 +209,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -233,11 +233,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -257,11 +257,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -281,11 +281,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -305,7 +305,7 @@ "browser": [ { "comment": "expect a login page with logo", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect a login page with logo", @@ -329,7 +329,7 @@ "browser": [ { "comment": "expect a login page with policy document link", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect a login page with policy document link", @@ -353,7 +353,7 @@ "browser": [ { "comment": "expect a login page with TOS document link", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect a login page with TOS document link", @@ -376,7 +376,7 @@ "oidcc-rp-initiated-logout-bad-post-logout-redirect-uri": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -440,7 +440,7 @@ "oidcc-rp-initiated-logout-query-added-to-post-logout-redirect-uri": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -504,7 +504,7 @@ "oidcc-rp-initiated-logout-modified-id-token-hint": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -568,7 +568,7 @@ "oidcc-rp-initiated-logout-bad-id-token-hint": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -632,7 +632,7 @@ "oidcc-rp-initiated-logout-no-id-token-hint": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -696,7 +696,7 @@ "oidcc-rp-initiated-logout-no-params": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -760,7 +760,7 @@ "oidcc-rp-initiated-logout-no-post-logout-redirect-uri": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -824,7 +824,7 @@ "oidcc-rp-initiated-logout-only-state": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", diff --git a/conformance-tests/conformance-basic-ci.json b/conformance-tests/conformance-basic-ci.json index 62ad6b32..b781d2f2 100644 --- a/conformance-tests/conformance-basic-ci.json +++ b/conformance-tests/conformance-basic-ci.json @@ -18,7 +18,7 @@ }, "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -87,7 +87,7 @@ "browser": [ { "comment": "updates placeholder during the second authorization", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -140,7 +140,7 @@ "browser": [ { "comment": "updates placeholder during the second authorization", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -193,11 +193,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -217,11 +217,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -241,11 +241,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -265,11 +265,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -289,11 +289,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -313,7 +313,7 @@ "browser": [ { "comment": "expect a login page with logo", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect a login page with logo", @@ -337,7 +337,7 @@ "browser": [ { "comment": "expect a login page with policy document link", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect a login page with policy document link", @@ -361,7 +361,7 @@ "browser": [ { "comment": "expect a login page with TOS document link", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect a login page with TOS document link", @@ -384,7 +384,7 @@ "oidcc-rp-initiated-logout-bad-post-logout-redirect-uri": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -448,7 +448,7 @@ "oidcc-rp-initiated-logout-query-added-to-post-logout-redirect-uri": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -512,7 +512,7 @@ "oidcc-rp-initiated-logout-modified-id-token-hint": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -576,7 +576,7 @@ "oidcc-rp-initiated-logout-bad-id-token-hint": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -640,7 +640,7 @@ "oidcc-rp-initiated-logout-no-id-token-hint": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -704,7 +704,7 @@ "oidcc-rp-initiated-logout-no-params": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -768,7 +768,7 @@ "oidcc-rp-initiated-logout-no-post-logout-redirect-uri": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -832,7 +832,7 @@ "oidcc-rp-initiated-logout-only-state": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", diff --git a/conformance-tests/conformance-implicit-ci.json b/conformance-tests/conformance-implicit-ci.json index e5e8f4de..bdbdbe1f 100644 --- a/conformance-tests/conformance-implicit-ci.json +++ b/conformance-tests/conformance-implicit-ci.json @@ -18,7 +18,7 @@ }, "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -111,7 +111,7 @@ "browser": [ { "comment": "updates placeholder during the second authorization", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -179,7 +179,7 @@ "browser": [ { "comment": "updates placeholder during the second authorization", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -247,11 +247,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -271,11 +271,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -295,11 +295,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -319,11 +319,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -343,11 +343,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -367,7 +367,7 @@ "browser": [ { "comment": "expect a login page with logo", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect a login page with logo", @@ -391,7 +391,7 @@ "browser": [ { "comment": "expect a login page with policy document link", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect a login page with policy document link", @@ -415,7 +415,7 @@ "browser": [ { "comment": "expect a login page with TOS document link", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect a login page with TOS document link", @@ -438,7 +438,7 @@ "oidcc-rp-initiated-logout-bad-post-logout-redirect-uri": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -517,7 +517,7 @@ "oidcc-rp-initiated-logout-query-added-to-post-logout-redirect-uri": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -596,7 +596,7 @@ "oidcc-rp-initiated-logout-modified-id-token-hint": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -675,7 +675,7 @@ "oidcc-rp-initiated-logout-bad-id-token-hint": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -754,7 +754,7 @@ "oidcc-rp-initiated-logout-no-id-token-hint": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -833,7 +833,7 @@ "oidcc-rp-initiated-logout-no-params": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -923,7 +923,7 @@ "oidcc-rp-initiated-logout-no-post-logout-redirect-uri": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -1013,7 +1013,7 @@ "oidcc-rp-initiated-logout-only-state": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", diff --git a/conformance-tests/conformance-rp-initiated-logout-ci.json b/conformance-tests/conformance-rp-initiated-logout-ci.json index 3c600c80..7b846676 100644 --- a/conformance-tests/conformance-rp-initiated-logout-ci.json +++ b/conformance-tests/conformance-rp-initiated-logout-ci.json @@ -10,7 +10,7 @@ }, "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -79,7 +79,7 @@ "browser": [ { "comment": "updates placeholder during the second authorization", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -132,7 +132,7 @@ "browser": [ { "comment": "updates placeholder during the second authorization", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -185,11 +185,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -209,11 +209,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -233,11 +233,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -257,11 +257,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -281,11 +281,11 @@ "browser": [ { "comment": "expect an immediate error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect redirect uri mismatch error page", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "commands": [ [ "wait", @@ -305,7 +305,7 @@ "browser": [ { "comment": "expect a login page with logo", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect a login page with logo", @@ -329,7 +329,7 @@ "browser": [ { "comment": "expect a login page with policy document link", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect a login page with policy document link", @@ -353,7 +353,7 @@ "browser": [ { "comment": "expect a login page with TOS document link", - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Expect a login page with TOS document link", @@ -376,7 +376,7 @@ "oidcc-rp-initiated-logout-bad-post-logout-redirect-uri": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -440,7 +440,7 @@ "oidcc-rp-initiated-logout-query-added-to-post-logout-redirect-uri": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -504,7 +504,7 @@ "oidcc-rp-initiated-logout-modified-id-token-hint": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -568,7 +568,7 @@ "oidcc-rp-initiated-logout-bad-id-token-hint": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -632,7 +632,7 @@ "oidcc-rp-initiated-logout-no-id-token-hint": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -696,7 +696,7 @@ "oidcc-rp-initiated-logout-no-params": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -760,7 +760,7 @@ "oidcc-rp-initiated-logout-no-post-logout-redirect-uri": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", @@ -824,7 +824,7 @@ "oidcc-rp-initiated-logout-only-state": { "browser": [ { - "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorize.php*", + "match": "https://op.local.stack-dev.cirrusidentity.com/simplesaml/module.php/oidc/authorization*", "tasks": [ { "task": "Login", diff --git a/docker/conformance.sql b/docker/conformance.sql index 489fd9d7..f0ac4761 100644 --- a/docker/conformance.sql +++ b/docker/conformance.sql @@ -12,6 +12,8 @@ INSERT INTO oidc_migration_versions VALUES('20210902113500'); INSERT INTO oidc_migration_versions VALUES('20210908143500'); INSERT INTO oidc_migration_versions VALUES('20210916153400'); INSERT INTO oidc_migration_versions VALUES('20210916173400'); +INSERT INTO oidc_migration_versions VALUES('20240603141400'); +INSERT INTO oidc_migration_versions VALUES('20240605145700'); CREATE TABLE oidc_user ( id VARCHAR(191) PRIMARY KEY NOT NULL, claims TEXT, @@ -30,15 +32,17 @@ CREATE TABLE oidc_client ( is_confidential BOOLEAN NOT NULL DEFAULT false, owner VARCHAR(191) NULL, post_logout_redirect_uri TEXT NULL, - backchannel_logout_uri TEXT NULL + backchannel_logout_uri TEXT NULL, + entity_identifier VARCHAR(255) NULL, + client_registration_types VARCHAR(255) NULL ); -- Used 'httpd' host for back-channel logout url (https://httpd:8443/test/a/simplesamlphp-module-oidc/backchannel_logout) -- since this is the hostname of conformance server while running in container environment -INSERT INTO oidc_client VALUES('_55a99a1d298da921cb27d700d4604352e51171ebc4','_8967dd97d07cc59db7055e84ac00e79005157c1132','Conformance Client 1',replace('Client 1 for Conformance Testing https://openid.net/certification/connect_op_testing/\n','\n',char(10)),'example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email","address","phone","offline_access"]',1,1,NULL,'["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/post_logout_redirect"]','https://httpd:8443/test/a/simplesamlphp-module-oidc/backchannel_logout'); -INSERT INTO oidc_client VALUES('_34efb61060172a11d62101bc804db789f8f9100b0e','_91a4607a1c10ba801268929b961b3f6c067ff82d21','Conformance Client 2','','example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email","offline_access"]',1,1,NULL,NULL,NULL); -INSERT INTO oidc_client VALUES('_0afb7d18e54b2de8205a93e38ca119e62ee321d031','_944e73bbeec7850d32b68f1b5c780562c955967e4e','Conformance Client 3','Client for client_secret_post','example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email"]',1,1,NULL,NULL,NULL); -INSERT INTO oidc_client VALUES('_8957eda35234902ba8343c0cdacac040310f17dfca','_322d16999f9da8b5abc9e9c0c08e853f60f4dc4804','RP-Initiated Logout Client','Client for testing RP-Initiated Logout','example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email","address","phone"]',1,1,NULL,'["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/post_logout_redirect"]',NULL); -INSERT INTO oidc_client VALUES('_9fe2f7589ece1b71f5ef75a91847d71bc5125ec2a6','_3c0beb20194179c01d7796c6836f62801e9ed4b368','Back-Channel Logout Client','Client for testing Back-Channel Logout','example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email","address","phone"]',1,1,NULL,'["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/post_logout_redirect"]','https://httpd:8443/test/a/simplesamlphp-module-oidc/backchannel_logout'); +INSERT INTO oidc_client VALUES('_55a99a1d298da921cb27d700d4604352e51171ebc4','_8967dd97d07cc59db7055e84ac00e79005157c1132','Conformance Client 1',replace('Client 1 for Conformance Testing https://openid.net/certification/connect_op_testing/\n','\n',char(10)),'example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email","address","phone","offline_access"]',1,1,NULL,'["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/post_logout_redirect"]','https://httpd:8443/test/a/simplesamlphp-module-oidc/backchannel_logout',NULL,NULL); +INSERT INTO oidc_client VALUES('_34efb61060172a11d62101bc804db789f8f9100b0e','_91a4607a1c10ba801268929b961b3f6c067ff82d21','Conformance Client 2','','example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email","offline_access"]',1,1,NULL,NULL,NULL,NULL,NULL); +INSERT INTO oidc_client VALUES('_0afb7d18e54b2de8205a93e38ca119e62ee321d031','_944e73bbeec7850d32b68f1b5c780562c955967e4e','Conformance Client 3','Client for client_secret_post','example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email"]',1,1,NULL,NULL,NULL,NULL,NULL); +INSERT INTO oidc_client VALUES('_8957eda35234902ba8343c0cdacac040310f17dfca','_322d16999f9da8b5abc9e9c0c08e853f60f4dc4804','RP-Initiated Logout Client','Client for testing RP-Initiated Logout','example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email","address","phone"]',1,1,NULL,'["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/post_logout_redirect"]',NULL,NULL,NULL); +INSERT INTO oidc_client VALUES('_9fe2f7589ece1b71f5ef75a91847d71bc5125ec2a6','_3c0beb20194179c01d7796c6836f62801e9ed4b368','Back-Channel Logout Client','Client for testing Back-Channel Logout','example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email","address","phone"]',1,1,NULL,'["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/post_logout_redirect"]','https://httpd:8443/test/a/simplesamlphp-module-oidc/backchannel_logout',NULL,NULL); CREATE TABLE oidc_access_token ( id VARCHAR(191) PRIMARY KEY NOT NULL, scopes TEXT, diff --git a/routing/routes/routes.php b/routing/routes/routes.php index bd820f47..00ddf0e9 100644 --- a/routing/routes/routes.php +++ b/routing/routes/routes.php @@ -1,9 +1,14 @@ add(RoutesEnum::OpenIdConfiguration->name, RoutesEnum::OpenIdConfiguration->value) ->controller(ConfigurationDiscoveryController::class); + $routes->add(RoutesEnum::OpenIdAuthorization->name, RoutesEnum::OpenIdAuthorization->value) + ->controller([AuthorizationController::class, 'authorize']); + + /** + * OpenID Federation related routes. + */ $routes->add(RoutesEnum::OpenIdFederationConfiguration->name, RoutesEnum::OpenIdFederationConfiguration->value) ->controller([EntityStatementController::class, 'configuration']) ->methods([HttpMethodsEnum::GET->value]); diff --git a/routing/services/services.yml b/routing/services/services.yml index 5eeca754..5b3c200e 100644 --- a/routing/services/services.yml +++ b/routing/services/services.yml @@ -11,6 +11,11 @@ services: League\OAuth2\Server\Repositories\ScopeRepositoryInterface: '@SimpleSAML\Module\oidc\Repositories\ScopeRepository' League\OAuth2\Server\CryptKey|string $privateKey: '@oidc.key.private' League\OAuth2\Server\CryptKey|string $publicKey: '@oidc.key.public' + Psr\Http\Message\ServerRequestFactoryInterface: '@Laminas\Diactoros\ServerRequestFactory' + Psr\Http\Message\RequestFactoryInterface: '@Laminas\Diactoros\RequestFactory' + Psr\Http\Message\ResponseFactoryInterface: '@Laminas\Diactoros\ResponseFactory' + Psr\Http\Message\StreamFactoryInterface: '@Laminas\Diactoros\StreamFactory' + Psr\Http\Message\UploadedFileFactoryInterface: '@Laminas\Diactoros\UploadedFileFactory' SimpleSAML\Module\oidc\Services\: resource: '../../src/Services/*' @@ -26,8 +31,25 @@ services: SimpleSAML\Module\oidc\Stores\: resource: '../../src/Stores/*' + SimpleSAML\Module\oidc\Bridges\: + resource: '../../src/Bridges/*' + SimpleSAML\Module\oidc\ModuleConfig: ~ SimpleSAML\Module\oidc\Forms\Controls\CsrfProtection: ~ + SimpleSAML\Module\oidc\Utils\Checker\RequestRulesManager: + factory: ['@SimpleSAML\Module\oidc\Factories\RequestRulesManagerFactory', 'build'] + # Grants + SimpleSAML\Module\oidc\Server\Grants\AuthCodeGrant: + factory: ['@SimpleSAML\Module\oidc\Factories\Grant\AuthCodeGrantFactory', 'build'] + SimpleSAML\Module\oidc\Server\Grants\OAuth2ImplicitGrant: + factory: ['@SimpleSAML\Module\oidc\Factories\Grant\OAuth2ImplicitGrantFactory', 'build'] + SimpleSAML\Module\oidc\Server\Grants\ImplicitGrant: + factory: ['@SimpleSAML\Module\oidc\Factories\Grant\ImplicitGrantFactory', 'build'] + SimpleSAML\Module\oidc\Server\Grants\RefreshTokenGrant: + factory: ['@SimpleSAML\Module\oidc\Factories\Grant\RefreshTokenGrantFactory', 'build'] + # Responses + SimpleSAML\Module\oidc\Server\ResponseTypes\IdTokenResponse: + factory: ['@SimpleSAML\Module\oidc\Factories\IdTokenResponseFactory', 'build'] oidc.key.private: class: League\OAuth2\Server\CryptKey @@ -40,16 +62,31 @@ services: SimpleSAML\Module\oidc\Factories\ResourceServerFactory: arguments: $publicKey: '@oidc.key.public' + SimpleSAML\Module\oidc\Factories\AuthorizationServerFactory: + arguments: + $privateKey: '@oidc.key.private' + SimpleSAML\Module\oidc\Factories\IdTokenResponseFactory: + arguments: + $privateKey: '@oidc.key.private' SimpleSAML\Module\oidc\Utils\ClaimTranslatorExtractor: - arguments: - $userIdAttr: '@=service("SimpleSAML\\Module\\oidc\\ModuleConfig").getUserIdentifierAttribute()' + factory: ['@SimpleSAML\Module\oidc\Factories\ClaimTranslatorExtractorFactory', 'build'] SimpleSAML\Module\oidc\Server\AuthorizationServer: - arguments: - $encryptionKey: '@=service("SimpleSAML\\Module\\oidc\\ModuleConfig").getEncryptionKey()' + factory: ['@SimpleSAML\Module\oidc\Factories\AuthorizationServerFactory', 'build'] + # OAuth2 Server League\OAuth2\Server\ResourceServer: arguments: $publicKey: '@oidc.key.public' + + # Use (already available) Laminas\Diactoros package as PSR HTTP Factories. + Laminas\Diactoros\ServerRequestFactory: ~ + Laminas\Diactoros\RequestFactory: ~ + Laminas\Diactoros\ResponseFactory: ~ + Laminas\Diactoros\StreamFactory: ~ + Laminas\Diactoros\UploadedFileFactory: ~ + + # Symfony + Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory: ~ diff --git a/src/Bridges/PsrHttpBridge.php b/src/Bridges/PsrHttpBridge.php new file mode 100644 index 00000000..2cf9293b --- /dev/null +++ b/src/Bridges/PsrHttpBridge.php @@ -0,0 +1,62 @@ +psrHttpFactory = new PsrHttpFactory( + $this->serverRequestFactory, + $this->streamFactory, + $this->uploadedFileFactory, + $this->responseFactory, + ); + } + + public function getHttpFoundationFactory(): HttpFoundationFactory + { + return $this->httpFoundationFactory; + } + + public function getServerRequestFactory(): ServerRequestFactoryInterface + { + return $this->serverRequestFactory; + } + + public function getResponseFactory(): ResponseFactoryInterface + { + return $this->responseFactory; + } + + public function getStreamFactory(): StreamFactoryInterface + { + return $this->streamFactory; + } + + public function getUploadedFileFactory(): UploadedFileFactoryInterface + { + return $this->uploadedFileFactory; + } + + public function getPsrHttpFactory(): PsrHttpFactory + { + return $this->psrHttpFactory; + } +} diff --git a/src/Codebooks/RoutesEnum.php b/src/Codebooks/RoutesEnum.php index 2ed09e3c..8c0c424b 100644 --- a/src/Codebooks/RoutesEnum.php +++ b/src/Codebooks/RoutesEnum.php @@ -6,6 +6,7 @@ enum RoutesEnum: string { + case OpenIdAuthorization = 'authorization'; case OpenIdConfiguration = '.well-known/openid-configuration'; case OpenIdFederationConfiguration = '.well-known/openid-federation'; case OpenIdFederationFetch = 'federation/fetch'; diff --git a/src/Controller/AuthorizationController.php b/src/Controller/AuthorizationController.php index 20988720..5e1f9a14 100644 --- a/src/Controller/AuthorizationController.php +++ b/src/Controller/AuthorizationController.php @@ -16,15 +16,19 @@ namespace SimpleSAML\Module\oidc\Controller; -use Laminas\Diactoros\Response; -use Laminas\Diactoros\ServerRequest; +use League\OAuth2\Server\Exception\OAuthServerException; use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; +use SimpleSAML\Module\oidc\Bridges\PsrHttpBridge; use SimpleSAML\Module\oidc\ModuleConfig; use SimpleSAML\Module\oidc\Server\AuthorizationServer; use SimpleSAML\Module\oidc\Server\Exceptions\OidcServerException; use SimpleSAML\Module\oidc\Server\RequestTypes\AuthorizationRequest; use SimpleSAML\Module\oidc\Services\AuthenticationService; +use SimpleSAML\Module\oidc\Services\ErrorResponder; use SimpleSAML\Module\oidc\Services\LoggerService; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; class AuthorizationController { @@ -33,6 +37,8 @@ public function __construct( private readonly AuthorizationServer $authorizationServer, private readonly ModuleConfig $moduleConfig, private readonly LoggerService $loggerService, + private readonly PsrHttpBridge $psrHttpBridge, + private readonly ErrorResponder $errorResponder, ) { } @@ -44,8 +50,11 @@ public function __construct( * @throws \SimpleSAML\Error\Exception * @throws \League\OAuth2\Server\Exception\OAuthServerException * @throws \Throwable + * + * @deprecated 7.0.0 Will be moved to Symfony controller method + * @see self::authorize() */ - public function __invoke(ServerRequest $request): ResponseInterface + public function __invoke(ServerRequestInterface $request): ResponseInterface { $authorizationRequest = $this->authorizationServer->validateAuthorizationRequest($request); @@ -62,7 +71,25 @@ public function __invoke(ServerRequest $request): ResponseInterface $this->validatePostAuthnAuthorizationRequest($authorizationRequest); } - return $this->authorizationServer->completeAuthorizationRequest($authorizationRequest, new Response()); + return $this->authorizationServer->completeAuthorizationRequest( + $authorizationRequest, + $this->psrHttpBridge->getResponseFactory()->createResponse(), + ); + } + + public function authorize(Request $request): Response + { + try { + /** + * @psalm-suppress DeprecatedMethod Until we drop support for old public/*.php routes, we need to bridge + * between PSR and Symfony HTTP messages. + */ + return $this->psrHttpBridge->getHttpFoundationFactory()->createResponse( + $this->__invoke($this->psrHttpBridge->getPsrHttpFactory()->createRequest($request)), + ); + } catch (OAuthServerException $exception) { + return $this->errorResponder->forException($exception); + } } /** diff --git a/src/Factories/AuthorizationServerFactory.php b/src/Factories/AuthorizationServerFactory.php index c3e6c03f..fe02f349 100644 --- a/src/Factories/AuthorizationServerFactory.php +++ b/src/Factories/AuthorizationServerFactory.php @@ -16,9 +16,8 @@ namespace SimpleSAML\Module\oidc\Factories; -use DateInterval; use League\OAuth2\Server\CryptKey; -use League\OAuth2\Server\Grant\RefreshTokenGrant; +use SimpleSAML\Module\oidc\ModuleConfig; use SimpleSAML\Module\oidc\Repositories\AccessTokenRepository; use SimpleSAML\Module\oidc\Repositories\ClientRepository; use SimpleSAML\Module\oidc\Repositories\ScopeRepository; @@ -26,12 +25,14 @@ use SimpleSAML\Module\oidc\Server\Grants\AuthCodeGrant; use SimpleSAML\Module\oidc\Server\Grants\ImplicitGrant; use SimpleSAML\Module\oidc\Server\Grants\OAuth2ImplicitGrant; +use SimpleSAML\Module\oidc\Server\Grants\RefreshTokenGrant; use SimpleSAML\Module\oidc\Server\ResponseTypes\IdTokenResponse; use SimpleSAML\Module\oidc\Utils\Checker\RequestRulesManager; class AuthorizationServerFactory { public function __construct( + private readonly ModuleConfig $moduleConfig, private readonly ClientRepository $clientRepository, private readonly AccessTokenRepository $accessTokenRepository, private readonly ScopeRepository $scopeRepository, @@ -39,11 +40,9 @@ public function __construct( private readonly OAuth2ImplicitGrant $oAuth2ImplicitGrant, private readonly ImplicitGrant $implicitGrant, private readonly RefreshTokenGrant $refreshTokenGrant, - private readonly DateInterval $accessTokenDuration, private readonly IdTokenResponse $idTokenResponse, private readonly RequestRulesManager $requestRulesManager, private readonly CryptKey $privateKey, - private readonly string $encryptionKey, ) { } @@ -54,29 +53,29 @@ public function build(): AuthorizationServer $this->accessTokenRepository, $this->scopeRepository, $this->privateKey, - $this->encryptionKey, + $this->moduleConfig->getEncryptionKey(), $this->idTokenResponse, $this->requestRulesManager, ); $authorizationServer->enableGrantType( $this->authCodeGrant, - $this->accessTokenDuration, + $this->moduleConfig->getAccessTokenDuration(), ); $authorizationServer->enableGrantType( $this->oAuth2ImplicitGrant, - $this->accessTokenDuration, + $this->moduleConfig->getAccessTokenDuration(), ); $authorizationServer->enableGrantType( $this->implicitGrant, - $this->accessTokenDuration, + $this->moduleConfig->getAccessTokenDuration(), ); $authorizationServer->enableGrantType( $this->refreshTokenGrant, - $this->accessTokenDuration, + $this->moduleConfig->getAccessTokenDuration(), ); return $authorizationServer; diff --git a/src/Factories/Grant/AuthCodeGrantFactory.php b/src/Factories/Grant/AuthCodeGrantFactory.php index ffc6e9e1..a6508ab7 100644 --- a/src/Factories/Grant/AuthCodeGrantFactory.php +++ b/src/Factories/Grant/AuthCodeGrantFactory.php @@ -16,7 +16,7 @@ namespace SimpleSAML\Module\oidc\Factories\Grant; -use DateInterval; +use SimpleSAML\Module\oidc\ModuleConfig; use SimpleSAML\Module\oidc\Repositories\AccessTokenRepository; use SimpleSAML\Module\oidc\Repositories\AuthCodeRepository; use SimpleSAML\Module\oidc\Repositories\RefreshTokenRepository; @@ -26,11 +26,10 @@ class AuthCodeGrantFactory { public function __construct( + private readonly ModuleConfig $moduleConfig, private readonly AuthCodeRepository $authCodeRepository, private readonly AccessTokenRepository $accessTokenRepository, private readonly RefreshTokenRepository $refreshTokenRepository, - private readonly DateInterval $refreshTokenDuration, - private readonly DateInterval $authCodeDuration, private readonly RequestRulesManager $requestRulesManager, ) { } @@ -44,10 +43,10 @@ public function build(): AuthCodeGrant $this->authCodeRepository, $this->accessTokenRepository, $this->refreshTokenRepository, - $this->authCodeDuration, + $this->moduleConfig->getAuthCodeDuration(), $this->requestRulesManager, ); - $authCodeGrant->setRefreshTokenTTL($this->refreshTokenDuration); + $authCodeGrant->setRefreshTokenTTL($this->moduleConfig->getRefreshTokenDuration()); return $authCodeGrant; } diff --git a/src/Factories/Grant/ImplicitGrantFactory.php b/src/Factories/Grant/ImplicitGrantFactory.php index c1c2b7cb..bbaa6fc6 100644 --- a/src/Factories/Grant/ImplicitGrantFactory.php +++ b/src/Factories/Grant/ImplicitGrantFactory.php @@ -15,7 +15,7 @@ */ namespace SimpleSAML\Module\oidc\Factories\Grant; -use DateInterval; +use SimpleSAML\Module\oidc\ModuleConfig; use SimpleSAML\Module\oidc\Repositories\AccessTokenRepository; use SimpleSAML\Module\oidc\Server\Grants\ImplicitGrant; use SimpleSAML\Module\oidc\Services\IdTokenBuilder; @@ -24,8 +24,8 @@ class ImplicitGrantFactory { public function __construct( + private readonly ModuleConfig $moduleConfig, private readonly IdTokenBuilder $idTokenBuilder, - private readonly DateInterval $accessTokenDuration, private readonly RequestRulesManager $requestRulesManager, private readonly AccessTokenRepository $accessTokenRepository, ) { @@ -35,7 +35,7 @@ public function build(): ImplicitGrant { return new ImplicitGrant( $this->idTokenBuilder, - $this->accessTokenDuration, + $this->moduleConfig->getAccessTokenDuration(), $this->accessTokenRepository, '#', $this->requestRulesManager, diff --git a/src/Factories/Grant/OAuth2ImplicitGrantFactory.php b/src/Factories/Grant/OAuth2ImplicitGrantFactory.php index 8480103e..231f38db 100644 --- a/src/Factories/Grant/OAuth2ImplicitGrantFactory.php +++ b/src/Factories/Grant/OAuth2ImplicitGrantFactory.php @@ -15,20 +15,20 @@ */ namespace SimpleSAML\Module\oidc\Factories\Grant; -use DateInterval; +use SimpleSAML\Module\oidc\ModuleConfig; use SimpleSAML\Module\oidc\Server\Grants\OAuth2ImplicitGrant; use SimpleSAML\Module\oidc\Utils\Checker\RequestRulesManager; class OAuth2ImplicitGrantFactory { public function __construct( - private readonly DateInterval $accessTokenDuration, + private readonly ModuleConfig $moduleConfig, private readonly RequestRulesManager $requestRulesManager, ) { } public function build(): OAuth2ImplicitGrant { - return new OAuth2ImplicitGrant($this->accessTokenDuration, '#', $this->requestRulesManager); + return new OAuth2ImplicitGrant($this->moduleConfig->getAccessTokenDuration(), '#', $this->requestRulesManager); } } diff --git a/src/Factories/Grant/RefreshTokenGrantFactory.php b/src/Factories/Grant/RefreshTokenGrantFactory.php index babf98e7..d0bbefdc 100644 --- a/src/Factories/Grant/RefreshTokenGrantFactory.php +++ b/src/Factories/Grant/RefreshTokenGrantFactory.php @@ -15,22 +15,22 @@ */ namespace SimpleSAML\Module\oidc\Factories\Grant; -use DateInterval; +use SimpleSAML\Module\oidc\ModuleConfig; use SimpleSAML\Module\oidc\Repositories\RefreshTokenRepository; use SimpleSAML\Module\oidc\Server\Grants\RefreshTokenGrant; class RefreshTokenGrantFactory { public function __construct( + private readonly ModuleConfig $moduleConfig, private readonly RefreshTokenRepository $refreshTokenRepository, - private readonly DateInterval $refreshTokenDuration, ) { } public function build(): RefreshTokenGrant { $refreshTokenGrant = new RefreshTokenGrant($this->refreshTokenRepository); - $refreshTokenGrant->setRefreshTokenTTL($this->refreshTokenDuration); + $refreshTokenGrant->setRefreshTokenTTL($this->moduleConfig->getRefreshTokenDuration()); return $refreshTokenGrant; } diff --git a/src/Factories/IdTokenResponseFactory.php b/src/Factories/IdTokenResponseFactory.php index 2310fb1d..acc031bd 100644 --- a/src/Factories/IdTokenResponseFactory.php +++ b/src/Factories/IdTokenResponseFactory.php @@ -17,6 +17,7 @@ namespace SimpleSAML\Module\oidc\Factories; use League\OAuth2\Server\CryptKey; +use SimpleSAML\Module\oidc\ModuleConfig; use SimpleSAML\Module\oidc\Repositories\UserRepository; use SimpleSAML\Module\oidc\Server\ResponseTypes\IdTokenResponse; use SimpleSAML\Module\oidc\Services\IdTokenBuilder; @@ -24,10 +25,10 @@ class IdTokenResponseFactory { public function __construct( + private readonly ModuleConfig $moduleConfig, private readonly UserRepository $userRepository, private readonly IdTokenBuilder $idTokenBuilder, private readonly CryptKey $privateKey, - private readonly string $encryptionKey, ) { } @@ -38,7 +39,7 @@ public function build(): IdTokenResponse $this->idTokenBuilder, $this->privateKey, ); - $idTokenResponse->setEncryptionKey($this->encryptionKey); + $idTokenResponse->setEncryptionKey($this->moduleConfig->getEncryptionKey()); return $idTokenResponse; } diff --git a/src/Factories/RequestRulesManagerFactory.php b/src/Factories/RequestRulesManagerFactory.php new file mode 100644 index 00000000..21fb8093 --- /dev/null +++ b/src/Factories/RequestRulesManagerFactory.php @@ -0,0 +1,87 @@ +getDefaultRules(); + return new RequestRulesManager($rules, $this->logger); + } + + /** + * @return \SimpleSAML\Module\oidc\Utils\Checker\Interfaces\RequestRuleInterface[] + */ + private function getDefaultRules(): array + { + return [ + new StateRule(), + new ClientIdRule($this->clientRepository), + new RedirectUriRule(), + new RequestParameterRule(), + new PromptRule($this->authSimpleFactory, $this->authenticationService), + new MaxAgeRule($this->authSimpleFactory, $this->authenticationService), + new ScopeRule($this->scopeRepository), + new RequiredOpenIdScopeRule(), + new CodeChallengeRule(), + new CodeChallengeMethodRule($this->codeChallengeVerifiersRepository), + new RequestedClaimsRule($this->claimTranslatorExtractor), + new AddClaimsToIdTokenRule(), + new RequiredNonceRule(), + new ResponseTypeRule(), + new IdTokenHintRule($this->moduleConfig, $this->cryptKeyFactory), + new PostLogoutRedirectUriRule($this->clientRepository), + new UiLocalesRule(), + new AcrValuesRule(), + new ScopeOfflineAccessRule(), + ]; + } +} diff --git a/src/ModuleConfig.php b/src/ModuleConfig.php index 28a2c5b1..84c9ad1f 100644 --- a/src/ModuleConfig.php +++ b/src/ModuleConfig.php @@ -321,6 +321,15 @@ public function getProtocolPrivateKeyPassPhrase(): ?string return $this->config()->getOptionalString(self::OPTION_PKI_PRIVATE_KEY_PASSPHRASE, null); } + /** + * Used in services.yml. + * @return string + */ + public function getEncryptionKey(): string + { + return $this->sspBridge->utils()->config()->getSecretSalt(); + } + /** * Get autproc filters defined in the OIDC configuration. * @@ -483,4 +492,25 @@ public function getHomepageUri(): ?string null, ); } + + public function getAccessTokenDuration(): DateInterval + { + return new DateInterval( + $this->config()->getString(self::OPTION_TOKEN_ACCESS_TOKEN_TTL), + ); + } + + public function getAuthCodeDuration(): DateInterval + { + return new DateInterval( + $this->config()->getString(self::OPTION_TOKEN_AUTHORIZATION_CODE_TTL), + ); + } + + public function getRefreshTokenDuration(): DateInterval + { + return new DateInterval( + $this->config()->getString(self::OPTION_TOKEN_REFRESH_TOKEN_TTL), + ); + } } diff --git a/src/Services/Container.php b/src/Services/Container.php index de00f166..81b369a6 100644 --- a/src/Services/Container.php +++ b/src/Services/Container.php @@ -16,14 +16,22 @@ namespace SimpleSAML\Module\oidc\Services; -use DateInterval; +use Laminas\Diactoros\ResponseFactory; +use Laminas\Diactoros\ServerRequestFactory; +use Laminas\Diactoros\StreamFactory; +use Laminas\Diactoros\UploadedFileFactory; use League\OAuth2\Server\ResourceServer; use Psr\Container\ContainerInterface; use Psr\Container\NotFoundExceptionInterface; +use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\ServerRequestFactoryInterface; +use Psr\Http\Message\StreamFactoryInterface; +use Psr\Http\Message\UploadedFileFactoryInterface; use SimpleSAML\Configuration; use SimpleSAML\Database; use SimpleSAML\Error\Exception; use SimpleSAML\Metadata\MetaDataStorageHandler; +use SimpleSAML\Module\oidc\Bridges\PsrHttpBridge; use SimpleSAML\Module\oidc\Factories\AuthorizationServerFactory; use SimpleSAML\Module\oidc\Factories\AuthSimpleFactory; use SimpleSAML\Module\oidc\Factories\ClaimTranslatorExtractorFactory; @@ -77,7 +85,7 @@ use SimpleSAML\Module\oidc\Utils\Checker\Rules\UiLocalesRule; use SimpleSAML\Module\oidc\Utils\ClaimTranslatorExtractor; use SimpleSAML\Session; -use SimpleSAML\Utils\Config; +use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory; class Container implements ContainerInterface { @@ -206,18 +214,8 @@ public function __construct() $requestRuleManager = new RequestRulesManager($requestRules, $loggerService); $this->services[RequestRulesManager::class] = $requestRuleManager; - $accessTokenDuration = new DateInterval( - $moduleConfig->config()->getString(ModuleConfig::OPTION_TOKEN_ACCESS_TOKEN_TTL), - ); - $authCodeDuration = new DateInterval( - $moduleConfig->config()->getString(ModuleConfig::OPTION_TOKEN_AUTHORIZATION_CODE_TTL), - ); - $refreshTokenDuration = new DateInterval( - $moduleConfig->config()->getString(ModuleConfig::OPTION_TOKEN_REFRESH_TOKEN_TTL), - ); $publicKey = $cryptKeyFactory->buildPublicKey(); $privateKey = $cryptKeyFactory->buildPrivateKey(); - $encryptionKey = (new Config())->getSecretSalt(); $jsonWebTokenBuilderService = new JsonWebTokenBuilderService($moduleConfig); $this->services[JsonWebTokenBuilderService::class] = $jsonWebTokenBuilderService; @@ -235,41 +233,41 @@ public function __construct() $this->services[LogoutTicketStoreBuilder::class] = $sessionLogoutTicketStoreBuilder; $idTokenResponseFactory = new IdTokenResponseFactory( + $moduleConfig, $userRepository, $this->services[IdTokenBuilder::class], $privateKey, - $encryptionKey, ); $this->services[IdTokenResponse::class] = $idTokenResponseFactory->build(); $authCodeGrantFactory = new AuthCodeGrantFactory( + $moduleConfig, $authCodeRepository, $accessTokenRepository, $refreshTokenRepository, - $refreshTokenDuration, - $authCodeDuration, $requestRuleManager, ); $this->services[AuthCodeGrant::class] = $authCodeGrantFactory->build(); - $oAuth2ImplicitGrantFactory = new OAuth2ImplicitGrantFactory($accessTokenDuration, $requestRuleManager); + $oAuth2ImplicitGrantFactory = new OAuth2ImplicitGrantFactory($moduleConfig, $requestRuleManager); $this->services[OAuth2ImplicitGrant::class] = $oAuth2ImplicitGrantFactory->build(); $implicitGrantFactory = new ImplicitGrantFactory( + $moduleConfig, $this->services[IdTokenBuilder::class], - $accessTokenDuration, $requestRuleManager, $accessTokenRepository, ); $this->services[ImplicitGrant::class] = $implicitGrantFactory->build(); $refreshTokenGrantFactory = new RefreshTokenGrantFactory( + $moduleConfig, $refreshTokenRepository, - $refreshTokenDuration, ); $this->services[RefreshTokenGrant::class] = $refreshTokenGrantFactory->build(); $authorizationServerFactory = new AuthorizationServerFactory( + $moduleConfig, $clientRepository, $accessTokenRepository, $scopeRepository, @@ -277,11 +275,9 @@ public function __construct() $this->services[OAuth2ImplicitGrant::class], $this->services[ImplicitGrant::class], $this->services[RefreshTokenGrant::class], - $accessTokenDuration, $this->services[IdTokenResponse::class], $requestRuleManager, $privateKey, - $encryptionKey, ); $this->services[AuthorizationServer::class] = $authorizationServerFactory->build(); @@ -294,6 +290,33 @@ public function __construct() $bearerTokenValidator, ); $this->services[ResourceServer::class] = $resourceServerFactory->build(); + + $httpFoundationFactory = new HttpFoundationFactory(); + $this->services[HttpFoundationFactory::class] = $httpFoundationFactory; + + $serverRequestFactory = new ServerRequestFactory(); + $this->services[ServerRequestFactoryInterface::class] = $serverRequestFactory; + + $responseFactory = new ResponseFactory(); + $this->services[ResponseFactoryInterface::class] = $responseFactory; + + $streamFactory = new StreamFactory(); + $this->services[StreamFactoryInterface::class] = $streamFactory; + + $uploadedFileFactory = new UploadedFileFactory(); + $this->services[UploadedFileFactoryInterface::class] = $uploadedFileFactory; + + $psrHttpBridge = new PsrHttpBridge( + $httpFoundationFactory, + $serverRequestFactory, + $responseFactory, + $streamFactory, + $uploadedFileFactory, + ); + $this->services[PsrHttpBridge::class] = $psrHttpBridge; + + $errorResponder = new ErrorResponder($psrHttpBridge); + $this->services[ErrorResponder::class] = $errorResponder; } /** diff --git a/src/Services/ErrorResponder.php b/src/Services/ErrorResponder.php new file mode 100644 index 00000000..0b0cf348 --- /dev/null +++ b/src/Services/ErrorResponder.php @@ -0,0 +1,48 @@ +psrHttpBridge->getHttpFoundationFactory()->createResponse( + $exception->generateHttpResponse($this->psrHttpBridge->getResponseFactory()->createResponse()), + ); + } + + return new JsonResponse( + [ + 'error' => [ + 'code' => 500, + 'message' => $exception->getMessage(), + ], + ], + 500, + ); + } +} diff --git a/src/Services/OpMetadataService.php b/src/Services/OpMetadataService.php index 04cfcd28..4b02bc4a 100644 --- a/src/Services/OpMetadataService.php +++ b/src/Services/OpMetadataService.php @@ -4,6 +4,7 @@ namespace SimpleSAML\Module\oidc\Services; +use SimpleSAML\Module\oidc\Codebooks\RoutesEnum; use SimpleSAML\Module\oidc\ModuleConfig; /** @@ -34,7 +35,7 @@ private function initMetadata(): void $this->metadata = []; $this->metadata['issuer'] = $this->moduleConfig->getIssuer(); $this->metadata['authorization_endpoint'] = - $this->moduleConfig->getModuleUrl('authorize.php'); + $this->moduleConfig->getModuleUrl(RoutesEnum::OpenIdAuthorization->value); $this->metadata['token_endpoint'] = $this->moduleConfig->getModuleUrl('token.php'); $this->metadata['userinfo_endpoint'] = $this->moduleConfig->getModuleUrl('userinfo.php'); $this->metadata['end_session_endpoint'] = $this->moduleConfig->getModuleUrl('logout.php'); diff --git a/tests/src/Controller/AuthorizationControllerTest.php b/tests/src/Controller/AuthorizationControllerTest.php index dbd68393..a297a556 100644 --- a/tests/src/Controller/AuthorizationControllerTest.php +++ b/tests/src/Controller/AuthorizationControllerTest.php @@ -9,6 +9,7 @@ use PHPUnit\Framework\MockObject\Stub; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ResponseInterface; +use SimpleSAML\Module\oidc\Bridges\PsrHttpBridge; use SimpleSAML\Module\oidc\Controller\AuthorizationController; use SimpleSAML\Module\oidc\Entities\UserEntity; use SimpleSAML\Module\oidc\ModuleConfig; @@ -16,6 +17,7 @@ use SimpleSAML\Module\oidc\Server\Exceptions\OidcServerException; use SimpleSAML\Module\oidc\Server\RequestTypes\AuthorizationRequest; use SimpleSAML\Module\oidc\Services\AuthenticationService; +use SimpleSAML\Module\oidc\Services\ErrorResponder; use SimpleSAML\Module\oidc\Services\LoggerService; /** @@ -31,6 +33,8 @@ class AuthorizationControllerTest extends TestCase protected Stub $userEntityStub; protected Stub $serverRequestStub; protected Stub $responseStub; + protected MockObject $psrHttpBridgeMock; + protected MockObject $errorResponderMock; protected static string $sampleAuthSourceId = 'authSource123'; @@ -52,6 +56,9 @@ public function setUp(): void $this->userEntityStub = $this->createStub(UserEntity::class); $this->serverRequestStub = $this->createStub(ServerRequest::class); $this->responseStub = $this->createStub(ResponseInterface::class); + + $this->psrHttpBridgeMock = $this->createMock(PsrHttpBridge::class); + $this->errorResponderMock = $this->createMock(ErrorResponder::class); } /** @@ -78,6 +85,8 @@ public function testReturnsResponseWhenInvoked(): void $this->authorizationServerStub, $this->moduleConfigStub, $this->loggerServiceMock, + $this->psrHttpBridgeMock, + $this->errorResponderMock, ); $this->assertInstanceOf(ResponseInterface::class, $controller($this->serverRequestStub)); @@ -108,6 +117,8 @@ public function testValidateAcrThrowsIfAuthSourceIdNotSetInAuthorizationRequest( $this->authorizationServerStub, $this->moduleConfigStub, $this->loggerServiceMock, + $this->psrHttpBridgeMock, + $this->errorResponderMock, ))($this->serverRequestStub); } @@ -138,6 +149,8 @@ public function testValidateAcrThrowsIfCookieBasedAuthnNotSetInAuthorizationRequ $this->authorizationServerStub, $this->moduleConfigStub, $this->loggerServiceMock, + $this->psrHttpBridgeMock, + $this->errorResponderMock, ))($this->serverRequestStub); } @@ -177,6 +190,8 @@ public function testValidateAcrSetsForcedAcrForCookieAuthentication(): void $this->authorizationServerStub, $this->moduleConfigStub, $this->loggerServiceMock, + $this->psrHttpBridgeMock, + $this->errorResponderMock, ))($this->serverRequestStub); } @@ -216,6 +231,8 @@ public function testValidateAcrThrowsIfNoMatchedAcrForEssentialAcrs(): void $this->authorizationServerStub, $this->moduleConfigStub, $this->loggerServiceMock, + $this->psrHttpBridgeMock, + $this->errorResponderMock, ))($this->serverRequestStub); } @@ -254,6 +271,8 @@ public function testValidateAcrSetsFirstMatchedAcr(): void $this->authorizationServerStub, $this->moduleConfigStub, $this->loggerServiceMock, + $this->psrHttpBridgeMock, + $this->errorResponderMock, ))($this->serverRequestStub); } @@ -293,6 +312,8 @@ public function testValidateAcrSetsCurrentSessionAcrIfNoMatchedAcr(): void $this->authorizationServerStub, $this->moduleConfigStub, $this->loggerServiceMock, + $this->psrHttpBridgeMock, + $this->errorResponderMock, ))($this->serverRequestStub); } @@ -333,6 +354,8 @@ public function testValidateAcrLogsWarningIfNoAcrsConfigured(): void $this->authorizationServerStub, $this->moduleConfigStub, $this->loggerServiceMock, + $this->psrHttpBridgeMock, + $this->errorResponderMock, ))($this->serverRequestStub); } } diff --git a/tests/src/Services/OpMetadataServiceTest.php b/tests/src/Services/OpMetadataServiceTest.php index 07102881..c04e953a 100644 --- a/tests/src/Services/OpMetadataServiceTest.php +++ b/tests/src/Services/OpMetadataServiceTest.php @@ -7,6 +7,7 @@ use Lcobucci\JWT\Signer\Rsa; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; +use SimpleSAML\Module\oidc\Codebooks\RoutesEnum; use SimpleSAML\Module\oidc\ModuleConfig; use SimpleSAML\Module\oidc\Services\OpMetadataService; @@ -31,7 +32,7 @@ public function setUp(): void $this->moduleConfigMock->method('getModuleUrl') ->willReturnCallback(function ($path) { $paths = [ - 'authorize.php' => 'http://localhost/authorize.php', + RoutesEnum::OpenIdAuthorization->value => 'http://localhost/authorization', 'token.php' => 'http://localhost/token.php', 'userinfo.php' => 'http://localhost/userinfo.php', 'jwks.php' => 'http://localhost/jwks.php', @@ -74,7 +75,7 @@ public function testItReturnsExpectedMetadata(): void $this->assertSame( [ 'issuer' => 'http://localhost', - 'authorization_endpoint' => 'http://localhost/authorize.php', + 'authorization_endpoint' => 'http://localhost/authorization', 'token_endpoint' => 'http://localhost/token.php', 'userinfo_endpoint' => 'http://localhost/userinfo.php', 'end_session_endpoint' => 'http://localhost/logout.php',