2016-04-06 34 views
1

問題


我希望用戶經由被作爲GET參數到第一請求中提供的訪問令牌進行認證。驗證用戶在Symfony的3

我從來沒有在Symfony中實現這樣的事情,所以我遵循How to Create a custom Authentication Provider中列出的步驟,但它不起作用。沒有觸發AuthenticationProviderInterfaceauthenticate方法。

我已經試過


因爲它是很多的配置居多,我甚至不知道如何調試這一點。這是我迄今得出的結論:只有AccessTokenProvider被構建,沒有別的。

代碼


這些是該系統的相關部分:

security.yml

security: 

    # Snip default (empty) in_memory provider 

    firewalls: 
     # Snip dev and main (symfony default) 

     accesstoken_secured: 
      pattern:  ^/admin/ 
      accesstoken: true 

services.yml

services: 
    accesstoken.security.authentication.provider: 
     class: AppBundle\Security\Authentication\Provider\AccessTokenProvider 
     arguments: 
      - '' # User Provider 
      - '%kernel.cache_dir%/security/nonces' 
     public: false 

    accesstoken.security.authentication.listener: 
     class: AppBundle\Security\Firewall\AccessTokenListener 
     arguments: ['@security.token_storage', '@security.authentication.manager'] 
     public: false 

AccessTokenFactory

class AccessTokenFactory implements SecurityFactoryInterface 
{ 
    public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint) 
    { 
     $providerId = 'security.authentication.provider.accesstoken.'.$id; 
     $container 
      ->setDefinition($providerId, new DefinitionDecorator('accesstoken.security.authentication.provider')) 
      ->replaceArgument(0, new Reference($userProvider)) 
     ; 

     $listenerId = 'security.authentication.listener.accesstoken.'.$id; 
     $container->setDefinition($listenerId, new DefinitionDecorator('accesstoken.security.authentication.listener')); 

     return array($providerId, $listenerId, $defaultEntryPoint); 
    } 

    public function getPosition() 
    { 
     return 'pre_auth'; 
    } 

    public function getKey() 
    { 
     return 'accesstoken'; 
    } 

    public function addConfiguration(NodeDefinition $node) 
    { 
    } 
} 

AccessTokenProvider

class AccessTokenProvider implements AuthenticationProviderInterface 
{ 
    private $userProvider; 

    public function __construct(UserProviderInterface $userProvider) 
    { 
     $this->userProvider = $userProvider; 
    } 

    public function authenticate(TokenInterface $token) 
    { 
     $user = $this->userProvider->loadUserByAccessToken($token->getAttribute('token')); 

     if ($this->isTokenValid($token)) { 
      $authenticatedToken = new AccessToken(['role_user']); 
      $authenticatedToken->setUser($user); 

      return $authenticatedToken; 
     } 

     throw new AuthenticationException('The WSSE authentication failed.'); 
    } 

    protected function isTokenValid(AccessToken $token) 
    { 
     //TODO: Implement 
     return (bool)$token->token; 
    } 

    public function supports(TokenInterface $token) 
    { 
     return $token instanceof AccessToken; 
    } 
} 

AccessTokenListener

class AccessTokenListener 
{ 
    protected $tokenStorage; 
    protected $authenticationManager; 

    /** 
    * AccessTokenListener constructor. 
    * @param TokenStorageInterface $tokenStorage 
    * @param AuthenticationManagerInterface $authenticationManager 
    */ 
    public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager) 
    { 
     $this->tokenStorage = $tokenStorage; 
     $this->authenticationManager = $authenticationManager; 
    } 

    public function handle(GetResponseEvent $event) 
    { 
     $request = $event->getRequest(); 
     $accesstoken = $request->get('accesstoken'); 

     $token = new AccessToken(); 
     $token->token = $accesstoken; 

     try { 
      $authToken = $this->authenticationManager->authenticate($token); 
      $this->tokenStorage->setToken($authToken); 

      return; 
     } catch (AuthenticationException $failed) { 
      // ... you might log something here 
     } 

     // By default deny authorization 
     $response = new Response(); 
     $response->setStatusCode(Response::HTTP_FORBIDDEN); 
     $event->setResponse($response); 
    } 
} 

的accessToken

class AccessToken extends AbstractToken 
{ 
    public $token; 

    /** 
    * AccessToken constructor. 
    * @param array $roles 
    */ 
    public function __construct(array $roles = array()) 
    { 
     parent::__construct($roles); 

     // If the user has roles, consider it authenticated 
     $this->setAuthenticated(count($roles) > 0); 
    } 

    /** 
    * Returns the user credentials. 
    * 
    * @return mixed The user credentials 
    */ 
    public function getCredentials() 
    { 
     return ''; 
    } 
} 

回答