2015-12-20 47 views
4

找不到我做出授權由ApiKey,我想401 Unauthorized如果沒有授權的數據呈現,並且403 Forbidden如果授權數據是無效的。但是在兩種情況下我都得到了500 Internal Server Error安全throwns 500例外與令牌在TokenStorage,而不是403或401

security.yml

security: 

    providers: 
     api_key_user_provider: 
      entity: 
       class: RestBundle:RestUser 
       property: apikey 

    firewalls: 
     rest_api_area: 
      pattern: ^/api 
      stateless: true 
      rest_auth: 
       header: x-apikey 
      provider: api_key_user_provider 

    access_control: 
     - { path: ^/api, roles: ROLE_REST_USER } 

RestUserListener.php

class RestUserListener implements ListenerInterface 
{ 
    protected $tokenStorage; 
    protected $authenticationManager; 
    private $header; 

    function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, $header) 
    { 
     $this->tokenStorage = $tokenStorage; 
     $this->authenticationManager = $authenticationManager; 
     $this->header = $header; 
    } 

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

     $apikey = $request->headers->get($this->header); 
     if (!$apikey) return; 

     $token = new RestUserToken(); 
     $token->setUser($apikey); 

     $authToken = $this->authenticationManager->authenticate($token); 
     $this->tokenStorage->setToken($authToken); 
     return; 
    } 
} 

RestUserAuthenticationProvider.php:

class RestUserAuthenticationProvider implements AuthenticationProviderInterface 
{ 
    private $userProvider; 

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

    public function authenticate(TokenInterface $token) 
    { 
     $user = $this->userProvider->loadUserByUsername($token->getUsername()); 

     if ($user) 
     { 
      $authenticatedToken = new RestUserToken($user->getRoles()); 
      $authenticatedToken->setUser($user); 

      return $authenticatedToken; 
     } 

     throw new AuthenticationException("Apikey not found."); 
    } 

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

RestUserTokenAbstractToken一樣簡單,並且沒有額外的邏輯。

api_key_user_providerRestUser

RestUserFactory的apikey屬性標識的標準實體提供商也沒有額外的魔法裏面,就像官方文檔中

回答

2

RestUserListener::handle()方法應該處理的情況下,返回HTTP 401或HTTP 403.

僅僅有return;是不會做到這一點。

在類似的應用程序,我寫的,我這樣做:

use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException; 

// 
... 
// 

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

    if (/* something invalid here, so error */) { 
     $context = $request->getHost(); 

     throw new UnauthorizedHttpException(
      "Basic realm=\"$context\"", 
      'Please authenticate correctly or any other message here' 
     ); 
    } 
} 

投擲UnauthorizedHttpException將導致HTTP 401(你會明白,如果你將看到異常的源代碼)。

對於HTTP 403,您可以改爲使用Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException

+0

謝謝!真的很好的答案。我已經讓'hadle()'拋出'AuthenticationException',它在'KernelExceptionListener'中轉換爲適當的'HTTP'錯誤。 – Neka

+0

@Neka那麼它工作? :) –

+0

是的,它運作良好。但是,如果我想添加一個更多的身份驗證方法到'^/api'?你的解決方案將阻止所有其他auth方法,因爲它會拋出異常,並沒有給其他安全監聽器一個機會,不是嗎? – Neka