【发布时间】:2015-03-06 11:03:01
【问题描述】:
我为我的 api 设置了两种身份验证方法:
- 关注this tutorial的私有令牌验证器
- 用于access_token auth的FOSOAuthServerBundle系统:https://github.com/FriendsOfSymfony/FOSOAuthServerBundle
两者分别像一个魅力。
我尝试将这些系统与此安全配置结合起来:
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_ALLOWED_TO_SWITCH: ~
ROLE_SUPPORT: ~
ROLE_ADMIN: [ROLE_SONATA_ADMIN]
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_SUPPORT, ROLE_ALLOWED_TO_SWITCH]
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
api_key_user:
id: security.user.provider.api_key
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
oauth_token:
pattern: ^/oauth/v2/token
security: false
api:
pattern: ^/api
stateless: true
simple_preauth:
authenticator: security.authentication.authenticator.api_key
fos_oauth: true
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
login_path: /login
check_path: /login_check
anonymous: ~
logout:
path: /logout
switch_user: true
如果我尝试使用此 curl 命令获取访问令牌:
curl "http://localhost:8000/oauth/v2/token?client_id=1_2rqa1al0trwgso8g8co4swsks48cwsckgc8cokswkcgos4csog&client_secret=25a78plm6c2ss044k4skckkwoo8kw4kcoccg8sg0skook4sgwg&grant_type=password&username=test&password=test
它可以工作,我得到一个 access_token,但是当我尝试使用它时:
curl -X GET http://localhost:8000/api/changelogs.json -H "Authorization: Bearer MmI2OWNkNjhjMGYwOTUyNDA2OTdlMDBjNjA1YmI3MjVhNTBiMTNhMjI0MGE1YmM3NzgwNjVmZWZmYWNhM2E4YQ" | json_pp
我明白了:
{
"error" : "invalid_grant",
"error_description" : "The provided access token is invalid."
}
通过停用我的 single_preauth api 密钥身份验证器,它可以工作,我可以访问我的 API。
似乎我的 api 密钥验证器阻止了所有其他系统。
这里,我的 ApiKeyAuthenticator 类:
class ApiKeyAuthenticator implements SimplePreAuthenticatorInterface, AuthenticationFailureHandlerInterface
{
private $userProvider;
/**
* @param ApiKeyUserProvider $userProvider
*/
public function __construct(ApiKeyUserProvider $userProvider)
{
$this->userProvider = $userProvider;
}
/**
* {@inheritdoc}
*/
public function createToken(Request $request, $providerKey)
{
$apiKey = str_replace('Bearer ', '', $request->headers->get('Authorization', ''));
if (!$apiKey) {
throw new BadCredentialsException('No API key given.');
}
return new PreAuthenticatedToken('anon.', $apiKey, $providerKey);
}
/**
* {@inheritdoc}
*/
public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
{
$apiKey = $token->getCredentials();
$username = $this->userProvider->getUsernameForApiKey($apiKey);
if (!$username) {
throw new AuthenticationException('The provided access token is invalid.');
}
$user = $this->userProvider->loadUserByUsername($username);
return new PreAuthenticatedToken(
$user,
$apiKey,
$providerKey,
$user->getRoles()
);
}
/**
* {@inheritdoc}
*/
public function supportsToken(TokenInterface $token, $providerKey)
{
return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $providerKey;
}
/**
* {@inheritdoc}
*/
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
return new JsonResponse([
'error' => 'invalid_grant',
'error_description' => $exception->getMessage()
], 401);
}
}
但我找不到原因。
如何结合这两种验证器方法?
感谢您的帮助。
【问题讨论】:
标签: symfony authentication oauth-2.0 api-key