Refactor authentication system (#2602)
Make auth configuration available via UI, remove FOSUserBundle and SAML-Bundle dependency
This commit is contained in:
@@ -11,12 +11,14 @@ namespace App\Security;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Repository\UserRepository;
|
||||
use Exception;
|
||||
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
||||
use Symfony\Component\Security\Core\User\UserInterface as SecurityUserInterface;
|
||||
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
||||
|
||||
final class DoctrineUserProvider implements UserProviderInterface
|
||||
final class DoctrineUserProvider implements UserProviderInterface, PasswordUpgraderInterface
|
||||
{
|
||||
/**
|
||||
* @var UserRepository
|
||||
@@ -51,7 +53,7 @@ final class DoctrineUserProvider implements UserProviderInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function refreshUser(SecurityUserInterface $user)
|
||||
public function refreshUser(UserInterface $user)
|
||||
{
|
||||
if (!$user instanceof User) {
|
||||
throw new UnsupportedUserException(sprintf('Expected an instance of %s, but got "%s".', User::class, \get_class($user)));
|
||||
@@ -74,4 +76,15 @@ final class DoctrineUserProvider implements UserProviderInterface
|
||||
{
|
||||
return $class === User::class;
|
||||
}
|
||||
|
||||
public function upgradePassword(UserInterface $user, string $newEncodedPassword): void
|
||||
{
|
||||
if ($user instanceof User) {
|
||||
try {
|
||||
$user->setPassword($newEncodedPassword);
|
||||
$this->repository->saveUser($user);
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
91
src/Security/KimaiUserProvider.php
Normal file
91
src/Security/KimaiUserProvider.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Security;
|
||||
|
||||
use App\Configuration\SystemConfiguration;
|
||||
use App\Ldap\LdapUserProvider;
|
||||
use Symfony\Component\Security\Core\User\ChainUserProvider;
|
||||
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
||||
|
||||
class KimaiUserProvider implements UserProviderInterface, PasswordUpgraderInterface
|
||||
{
|
||||
private $providers;
|
||||
private $provider;
|
||||
private $configuration;
|
||||
|
||||
/**
|
||||
* @param iterable|UserProviderInterface[] $providers
|
||||
*/
|
||||
public function __construct(iterable $providers, SystemConfiguration $configuration)
|
||||
{
|
||||
$this->providers = $providers;
|
||||
$this->configuration = $configuration;
|
||||
}
|
||||
|
||||
private function getInternalProvider(): ChainUserProvider
|
||||
{
|
||||
if ($this->provider === null) {
|
||||
$activated = [];
|
||||
foreach ($this->providers as $provider) {
|
||||
if ($provider instanceof LdapUserProvider) {
|
||||
if (!$this->configuration->isLdapActive()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$activated[] = $provider;
|
||||
}
|
||||
$this->provider = new ChainUserProvider(new \ArrayIterator($activated));
|
||||
}
|
||||
|
||||
return $this->provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getProviders()
|
||||
{
|
||||
return $this->getInternalProvider()->getProviders();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadUserByUsername($username)
|
||||
{
|
||||
return $this->getInternalProvider()->loadUserByUsername($username);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function refreshUser(UserInterface $user)
|
||||
{
|
||||
return $this->getInternalProvider()->refreshUser($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsClass($class)
|
||||
{
|
||||
return $this->getInternalProvider()->supportsClass($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function upgradePassword(UserInterface $user, string $newEncodedPassword): void
|
||||
{
|
||||
$this->getInternalProvider()->upgradePassword($user, $newEncodedPassword);
|
||||
}
|
||||
}
|
||||
@@ -19,21 +19,16 @@ use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
||||
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
|
||||
use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface;
|
||||
|
||||
class TokenAuthenticator extends AbstractGuardAuthenticator
|
||||
class TokenAuthenticator extends AbstractGuardAuthenticator implements PasswordAuthenticatedInterface
|
||||
{
|
||||
public const HEADER_USERNAME = 'X-AUTH-USER';
|
||||
public const HEADER_TOKEN = 'X-AUTH-TOKEN';
|
||||
public const HEADER_JAVASCRIPT = 'X-AUTH-SESSION';
|
||||
|
||||
/**
|
||||
* @var EncoderFactoryInterface
|
||||
*/
|
||||
protected $encoderFactory;
|
||||
private $encoderFactory;
|
||||
|
||||
/**
|
||||
* @param EncoderFactoryInterface $encoderFactory
|
||||
*/
|
||||
public function __construct(EncoderFactoryInterface $encoderFactory)
|
||||
{
|
||||
$this->encoderFactory = $encoderFactory;
|
||||
@@ -163,4 +158,13 @@ class TokenAuthenticator extends AbstractGuardAuthenticator
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getPassword($credentials): ?string
|
||||
{
|
||||
if (!\is_array($credentials) || !\array_key_exists('token', $credentials) || empty($credentials['token'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $credentials['token'];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user