From a87a9190856fa3da038a123787784f273e49689f Mon Sep 17 00:00:00 2001 From: Evan Sims Date: Tue, 12 Dec 2023 04:14:35 -0500 Subject: [PATCH] feat(SDK-4733): Implement support for Back-Channel Logout (#167) --- config/definition.php | 6 +++ docs/BackchannelLogout.md | 14 +++++ example/config/packages/cache.yaml | 1 + src/Auth0Bundle.php | 7 ++- .../BackchannelLogoutController.php | 54 +++++++++++++++++++ 5 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 docs/BackchannelLogout.md create mode 100644 src/Controllers/BackchannelLogoutController.php diff --git a/config/definition.php b/config/definition.php index 1a6764a..adacd5a 100644 --- a/config/definition.php +++ b/config/definition.php @@ -120,6 +120,12 @@ ->scalarNode('event_listener_provider') ->defaultNull() ->end() + ->scalarNode('backchannel_logout_cache') + ->defaultNull() + ->end() + ->integerNode('backchannel_logout_expires') + ->defaultValue(2592000) + ->end() ->end() ->end() // sdk ->arrayNode('authenticator') diff --git a/docs/BackchannelLogout.md b/docs/BackchannelLogout.md new file mode 100644 index 0000000..a221118 --- /dev/null +++ b/docs/BackchannelLogout.md @@ -0,0 +1,14 @@ +# Backchannel Logout + +The Auth0 Symfony SDK supports [Backchannel Logout](https://auth0.com/docs/authenticate/login/logout/back-channel-logout) from v5.2 onward. To use this feature, some additional configuration is necessary: + +1. **Add a new route to your application.** This route must be publicly accessible. Auth0 will use it to send backchannel logout requests to your application. For example, from your `config/routes.yaml` file: + +```yaml +backchannel: # Retrieve backchannel logout tokens from Auth0 + path: /backckannel + controller: Auth0\Symfony\Controllers\BackchannelController::handle + methods: POST +``` + +2. **Configure your Auth0 tenant to use Backchannel Logout.** See the [Auth0 documentation](https://auth0.com/docs/authenticate/login/logout/back-channel-logout/configure-back-channel-logout) for more information on how to do this. Please ensure you point the Logout URI to the backchannel route we just added to your application. diff --git a/example/config/packages/cache.yaml b/example/config/packages/cache.yaml index 81ae55c..4553af7 100644 --- a/example/config/packages/cache.yaml +++ b/example/config/packages/cache.yaml @@ -20,3 +20,4 @@ framework: pools: auth0_token_cache: { adapter: cache.adapter.redis } auth0_management_token_cache: { adapter: cache.adapter.redis } + auth0_bachannel_logout_cache: { adapter: cache.adapter.redis } diff --git a/src/Auth0Bundle.php b/src/Auth0Bundle.php index 05cd272..ca603b5 100644 --- a/src/Auth0Bundle.php +++ b/src/Auth0Bundle.php @@ -30,6 +30,9 @@ public function loadExtension(array $config, ContainerConfigurator $container, C $managementTokenCache = $config['sdk']['management_token_cache'] ?? 'cache.app'; $managementTokenCache = new Reference($managementTokenCache); + $backchannelLogoutCache = $config['sdk']['backchannel_logout_cache'] ?? 'cache.app'; + $backchannelLogoutCache = new Reference($backchannelLogoutCache); + $transientStorage = new Reference($config['sdk']['transient_storage'] ?? 'auth0.store_transient'); $sessionStorage = new Reference($config['sdk']['session_storage'] ?? 'auth0.store_session'); @@ -126,7 +129,9 @@ public function loadExtension(array $config, ContainerConfigurator $container, C ->arg('$queryUserInfo', false) ->arg('$managementToken', $config['sdk']['management_token']) ->arg('$managementTokenCache', $managementTokenCache) - ->arg('$eventListenerProvider', $eventListenerProvider); + ->arg('$eventListenerProvider', $eventListenerProvider) + ->arg('$backchannelLogoutCache', $backchannelLogoutCache) + ->arg('$backchannelLogoutExpires', $config['sdk']['backchannel_logout_expires']); $container->services() ->set('auth0', Service::class) diff --git a/src/Controllers/BackchannelLogoutController.php b/src/Controllers/BackchannelLogoutController.php new file mode 100644 index 0000000..5b25faf --- /dev/null +++ b/src/Controllers/BackchannelLogoutController.php @@ -0,0 +1,54 @@ +getMethod()) { + return new Response('', Response::HTTP_METHOD_NOT_ALLOWED); + } + + $logoutToken = $request->get('logout_token'); + + if (! is_string($logoutToken)) { + return new Response('', Response::HTTP_BAD_REQUEST); + } + + $logoutToken = trim($logoutToken); + + if ('' === $logoutToken) { + return new Response('', Response::HTTP_BAD_REQUEST); + } + + try { + $this->getSdk()->handleBackchannelLogout($logoutToken); + } catch (Throwable $throwable) { + return new Response($throwable->getMessage(), Response::HTTP_BAD_REQUEST); + } + + return new Response('', Response::HTTP_OK); + } + + private function getSdk(): Auth0 + { + return $this->authenticator->service->getSdk(); + } +}