我通过ApiKey
进行授权,如果没有授权数据,我希望获得401 Unauthorized
,如果授权数据无效,我希望获得403 Forbidden
。但在这两种情况下我都得到500 Internal Server Error
。
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;
}
}
RestUserToken 就像AbstractToken
一样简单,没有其他逻辑。
api_key_user_provider 是由apikey
的{{1}}属性标识的标准实体提供商
RestUserFactory 里面也没有额外的魔法,就像在官方文档中那样
答案 0 :(得分: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
。