From b13655e95177d150cbe1457450d0d088d73a5816 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Tue, 21 Feb 2023 22:36:43 +0100 Subject: [PATCH] Prevent login of local users via SSO with the same username --- .../EnsureSAMLUserForSAMLLoginChecker.php | 63 +++++++++++++++++++ src/Security/UserChecker.php | 2 +- translations/security.en.xlf | 6 ++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 src/Security/EnsureSAMLUserForSAMLLoginChecker.php diff --git a/src/Security/EnsureSAMLUserForSAMLLoginChecker.php b/src/Security/EnsureSAMLUserForSAMLLoginChecker.php new file mode 100644 index 00000000..a65e6146 --- /dev/null +++ b/src/Security/EnsureSAMLUserForSAMLLoginChecker.php @@ -0,0 +1,63 @@ +. + */ + +namespace App\Security; + +use App\Entity\UserSystem\User; +use Hslavich\OneloginSamlBundle\Security\Http\Authenticator\Token\SamlToken; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent; +use Symfony\Component\Security\Core\Exception\AuthenticationException; +use Symfony\Component\Security\Core\Exception\CustomUserMessageAccountStatusException; +use Symfony\Contracts\Translation\TranslatorInterface; + +class EnsureSAMLUserForSAMLLoginChecker implements EventSubscriberInterface +{ + private TranslatorInterface $translator; + + public function __construct(TranslatorInterface $translator) + { + $this->translator = $translator; + } + + public static function getSubscribedEvents() + { + return [ + AuthenticationSuccessEvent::class => 'onAuthenticationSuccess', + ]; + } + + public function onAuthenticationSuccess(AuthenticationSuccessEvent $event) + { + $token = $event->getAuthenticationToken(); + $user = $token->getUser(); + + //If we are using SAML, we need to check that the user is a SAML user. + if ($token instanceof SamlToken) { + if ($user instanceof User && !$user->isSAMLUser()) { + throw new CustomUserMessageAccountStatusException($this->translator->trans('saml.error.cannot_login_local_user_per_saml', [], 'security')); + } + } else { //Ensure that you can not login locally with a SAML user (even if this should not happen, as the password is not set) + if ($user instanceof User && $user->isSamlUser()) { + throw new CustomUserMessageAccountStatusException($this->translator->trans('saml.error.cannot_login_saml_user_locally', [], 'security')); + } + } + } +} \ No newline at end of file diff --git a/src/Security/UserChecker.php b/src/Security/UserChecker.php index d42d3390..ae8e3f34 100644 --- a/src/Security/UserChecker.php +++ b/src/Security/UserChecker.php @@ -63,7 +63,7 @@ final class UserChecker implements UserCheckerInterface //Check if user is disabled. Then dont allow login if ($user->isDisabled()) { //throw new DisabledException(); - throw new CustomUserMessageAccountStatusException($this->translator->trans('user.login_error.user_disabled')); + throw new CustomUserMessageAccountStatusException($this->translator->trans('user.login_error.user_disabled', [], 'security')); } } } diff --git a/translations/security.en.xlf b/translations/security.en.xlf index 8c76136f..2c9d8957 100644 --- a/translations/security.en.xlf +++ b/translations/security.en.xlf @@ -7,5 +7,11 @@ Your account is disabled! Contact an administrator if you think this is wrong. + + + saml.error.cannot_login_local_user_per_saml + You can not login as local user via SSO! Use your local user password instead. + +