Symfony 2 - API密钥身份验证添加记住我

时间:2014-11-14 09:50:50

标签: symfony authentication remember-me

我是Symfony 2的新手,我需要通过链接和哈希来编写自定义登录代码。 我使用本教程创建了用户提供程序和用户身份验证器 - symfony 2 - api key auth

登录本身工作正常,但我正在努力“记住我”的功能。 您可以在“SECURITY.yml”的配置摘录中看到代码的相关部分,这会导致错误消息 - “RuntimeException:您必须为每个防火墙配置至少一个记住我的监听器(例如表单登录)记得 - 我启用了。“

security.yml

security:

role_hierarchy:
    ROLE_ADMIN:       ROLE_USER
    ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

providers:
    employee:
        id: employee_provider

firewalls:
    dev:
        pattern:  ^/(_(profiler|wdt)|css|images|js)/
        security: false

    access:
        pattern: ^/access$
        security: false

    main:
        pattern: ^/
        simple_preauth:
            authenticator: employee_authenticator
        logout:
            path:   logout_page
            target: forgotten_password_page
            invalidate_session: true
        remember_me:
            key:      "%secret%"
            lifetime: 3600 # 365 days in seconds
            path:     /
            domain:   ~ # Defaults to the current domain from $_SERVER
            always_remember_me: true
            remember_me_parameter: _remember_me

access_control:
    - { path: ^/admin, roles: [ROLE_MASTER] }

EmployeeAuthenticator

class EmployeeAuthenticator implements SimplePreAuthenticatorInterface, AuthenticationSuccessHandlerInterface, AuthenticationFailureHandlerInterface {

protected $router;
protected $httpUtils;
protected $loginCheckUrl;

public function __construct(Router $router, HttpUtils $httpUtils, $loginCheckUrl) {
    $this->router = $router;
    $this->httpUtils = $httpUtils;
    $this->loginCheckUrl = $loginCheckUrl;
}

private function isLoginUrl($request) {
    echo rawurldecode($request->getPathInfo());
    die();
}


public function createToken(Request $request, $providerKey) {
    $this->isLoginUrl($request);
    if (!$this->httpUtils->checkRequestPath($request, $this->loginCheckUrl)) {
        throw new AuthenticationException("Wrong login page");
    }

    $apiKey = $request->query->get('apikey');

    if (!$apiKey) {
        throw new BadCredentialsException('No API key found');
    }

    return new PreAuthenticatedToken(
            'anon.', $apiKey, $providerKey
    );
}

public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey) {
    $apiKey = $token->getCredentials();
    $employee = $token->getUser();

    if ($employee instanceof Employee) {
        return new PreAuthenticatedToken(
                $employee, $apiKey, $providerKey, $employee->getRoles()
        );
    }

    $employee = $userProvider->loadUserByUsername($apiKey);

    if (!$employee) {
        throw new AuthenticationException(
        sprintf('API Key "%s" does not exist.', $apiKey)
        );
    }

    return new PreAuthenticatedToken(
            $employee, $apiKey, $providerKey, $employee->getRoles()
    );
}

public function supportsToken(TokenInterface $token, $providerKey) {
    return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $providerKey;
}

public function onAuthenticationFailure(Request $request, AuthenticationException $exception) {
    $request->getSession()->getFlashBag()->add('notice', $exception->getMessage());

    return new RedirectResponse($this->router->generate('forgotten_password_page'));
}

public function onAuthenticationSuccess(Request $request, TokenInterface $token) {
    return new RedirectResponse($this->router->generate('homepage'));
}
}

EmployeeProvider

class EmployeeProvider implements UserProviderInterface {

private $repo;

public function __construct(ObjectManager $em) {
    $this->repo = $em->getRepository("MyWebBundle:Employee");
}

public function loadUserByUsername($hash) {

    $employee = $this->repo->loadUserByHash($hash);

    if ($employee) {
        return $employee;
    }

    throw new UsernameNotFoundException(
    sprintf('ApiKey is not exists "%s" does not exist.', $hash)
    );
}

public function refreshUser(UserInterface $employee) {
    if (!$employee instanceof Employee) {
        throw new UnsupportedUserException(
            sprintf('Instances of "%s" are not supported.', get_class($employee))
        );
    }

    return $this->repo->findOneById($employee->getId());
}

public function supportsClass($class) {
    return $class === 'My\WebBundle\Entity\Employee';
}

}

0 个答案:

没有答案