we are implemented a custom controller for one webspace of our sulu 2.6 installation. It requires login against our SSO, but the problem is, that the result is cached.
We have 4 Webspaces, just one should have this login protection. I found now also this article on User Context Caching but it appears to enable it for all webspaces.
Here is the current controller code
<?php
namespace App\Controller\Website;
use App\Service\SiteService;
use DWBN\VanillaSsoAuthentication\OAuth\AccessDeniedException;
use DWBN\VanillaSsoAuthentication\OAuth\ApplicationAccessDeniedException;
use Exception;
use Sulu\Bundle\WebsiteBundle\Controller\WebsiteController;
use Sulu\Component\Content\Compat\StructureInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use DWBN\VanillaSsoAuthentication\OAuth\OAuth2;
use Symfony\Component\Routing\Annotation\Route;
class SsoProtectedController extends WebsiteController
{
public function __construct(
private readonly SiteService $siteParameterService,
) {}
public function indexAction(StructureInterface $structure, $preview = false, $partial = false): Response // (3)
{
if (!$preview && !$partial) {
// initalize the sso
$this->initSso();
$user = OAuth2::get_user();
if (!$user->isAuthenticated()) {
$extra_state = array(
'remember_me' => true,
'next' => $this->container->get('request_stack')->getCurrentRequest()->getPathInfo()
);
$authentication_uri = OAuth2::get_authentication_uri( 'page', $extra_state);
return $this->redirect($authentication_uri);
}
}
return $this->renderStructure(
$structure,
[],
$preview,
$partial
);
}
#[Route(path: '/sso-login')]
public function loginAction(): Response
{
$error_message = null;
try {
$this->initSso();
OAuth2::login(true);
} catch (AccessDeniedException $e) {
$error_message = 'Authentication cancelled';
} catch (ApplicationAccessDeniedException $e) {
$error_message = 'Authorisation failed: ' . $e->getMessage();
} catch (Exception $e) {
$error_message = 'ERROR: ' . $e->getMessage();
}
// Render error template
return $this->render('mh_sso_login.html.twig', [
'error_message' => $error_message,
'request' => $this->container->get('request_stack')->getCurrentRequest(),
]);
}
#[Route(path: '/sso-logout')]
public function logoutAction()
{
$this->initSso();
OAuth2::logout();
$redirectTo = array_key_exists('next', $_GET) ? $_GET['next'] : '/';
return $this->redirect($redirectTo);
}
private function initSso(): void
{
$config = $this->siteParameterService->getSiteKey('sso', ['host' => 'https://sso-dev.default-url.org']);
$config['login_uri'] = $this->generateUrl('app_website_ssoprotected_login');
$config['logout_uri'] = $this->generateUrl('app_website_ssoprotected_logout');
$config['data_dir'] = $this->getParameter('kernel.project_dir') . '/var/cache/sso';
OAuth2::init($config, $config['host']);
}
}
I guess we have to integrate more closely with the symfony authorization mechanism? I found this cookbook entry but I don't fully understand it and it also feels a bit complicated. I only want to assure a binary logged-in or not protection and not create a lot of users in the sulu backend.
Any finger point in the right direction is highly appreciated.
In addition to @Alexanders answer, I managed to limit the logiin to a single webspace via this way:
config/packages/security.yaml
security:
providers:
sulu:
id: sulu_security.user_provider
sso_session:
id: App\Security\SsoSessionProvider
access_control:
# ...
- { path: ^/permission-denied, roles: [PUBLIC_ACCESS, IS_AUTHENTICATED_ANONYMOUSLY] }
- { path: ^/sso-login, roles: [PUBLIC_ACCESS, IS_AUTHENTICATED_ANONYMOUSLY] }
- { path: ^/, roles: FRONTEND_USER, host: '^(dev\.|www\.)?this-webspace(\.localhost|\.local|\.org)$' }
# ... all the rest
# and a dedicated setup for this single webspace, with host mapping
mahamudra_holders:
host: '^(dev\.|www\.)?this-webspace(\.localhost|\.local|\.org)$'
pattern: ^/
custom_authenticators:
- App\Security\SsoSessionAuthenticator
provider: sso_session
lazy: true
The SsoSessionAuthenticator is written as custom authenticator, as we don't want sulu users for all of them.