Symfony2 Custom Authenticator

时间:2013-12-24 06:18:15

标签: symfony

我正在尝试创建一个自定义身份验证器,我在这里遵循了教程:

http://symfony.com/doc/current/cookbook/security/custom_password_authenticator.html

但是我收到了这个错误:

ServiceNotFoundException: The service "security.authentication.manager" has a dependency on a non-existent service "security.user.provider.concrete.authenticator".

我检查了我的版本,我使用2.4,所以这不是问题,但似乎缺少symfony核心类?

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 }

身份验证

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;
    }
}

1 个答案:

答案 0 :(得分:6)

我认为你在这里混合了两件事。用户提供者和验证者。

在security.yml中,您告知防火墙使用提供商provider: authenticator,但在您的提供商部分中,您只有以下提供商:user_entity,因此您的用户提供商应为user_entity

如果您想了解有关提供商的更多信息,建议您阅读以下内容: http://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers