I'm trying to create a custom authenticator and I followed the tutorial here:
http://symfony.com/doc/current/cookbook/security/custom_password_authenticator.html
But I'm getting this error:
ServiceNotFoundException: The service "security.authentication.manager" has a dependency on a non-existent service "security.user.provider.concrete.authenticator".
I checked my version and I'm using 2.4, so thats not the issue but it seems like a symfony core class is missing?
Security.yml
security:
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
provider: authenticator
anonymous: ~
simple-form:
login_path: snap_front_login
check_path: login_check
authenticator: SnapsavedAuthenticator
encoders:
Snap\RestBundle\entity\User: plaintext
providers:
user_entity:
id: SnapsavedUserprovider
role_hierarchy:
ROLE_USER: ROLE_USER
ROLE_ADMIN: ROLE_ADMIN
ROLE_SUPER_ADMIN: [ROLE_SUPER_ADMIN, ROLE_ALLOWED_TO_SWITCH ]
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: ROLE_USER }
Authenticator
namespace Snap\ModelBundle\Security;
use Symfony\Component\Security\Core\Authentication\SimpleFormAuthenticatorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
class SnapsavedAuthenticator implements SimpleFormAuthenticatorInterface {
private $encoderFactory;
public function __construct(EncoderFactoryInterface $encoderFactory)
{
$this->encoderFactory = $encoderFactory;
}
public function createToken(Request $request, $username, $password, $providerKey)
{
return new UsernamePasswordToken($username, $password, $providerKey);
}
public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
{
try {
$user = $userProvider->loadUserByUsername($token->getUsername());
} catch (UsernameNotFoundException $e) {
throw new AuthenticationException('Invalid username or password');
}
$passwordValid = $this->encoderFactory->getEncoder($user)->isPasswordValid($user->getPassword(), $token->getCredentials(), $user->getSalt());
if ($passwordValid) {
$currentHour = date('G');
if ($currentHour < 14 || $currentHour > 16) {
throw new AuthenticationException('You can only log in between 2 and 4!', 100);
}
return new UsernamePasswordToken($user, 'bar', $providerKey, $user->getRoles());
}
throw new AuthenticationException('Invalid username or password');
}
public function supportsToken(TokenInterface $token, $providerKey)
{
return $token instanceof UsernamePasswordToken && $token->getProviderKey() === $providerKey;
}
}