我正在尝试使用SimpeFormAuthenticator通过oAuth使用我的API。但是,身份验证出了问题。
security:
encoders:
AdminBundle\Security\ApiUser: plaintext
providers:
admin.api_user_provider:
id: admin.api_user_provider
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/login$
anonymous: ~
admin:
pattern: ^/
provider: admin.api_user_provider
simple_form:
authenticator: admin.api_authenticator
login_path: admin_login
check_path: admin_login_check
role_hierarchy:
ROLE_FOO_SUPERADMIN : ROLE_FOO_ADMIN
ROLE_FOO_ADMIN : ROLE_FOO_USER
ROLE_USER : IS_AUTHENTICATED_ANONYMOUSLY
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: ROLE_FOO_ADMIN }
此配置按预期工作。
class ApiAuthenticator implements SimpleFormAuthenticatorInterface
{
private $apiCaller;
public function __construct($apiCaller)
{
$this->apiCaller = $apiCaller;
}
public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
{
// get roles from api server
$user = $userProvider->loadUserByUsername($token->getAccessToken());
return new ApiToken($user, $token, $providerKey, $user->getRoles());
}
public function supportsToken(TokenInterface $token, $providerKey)
{
return $token instanceof ApiToken && $token->getProviderKey() === $providerKey;
}
public function createToken(Request $request, $username, $password, $providerKey)
{
// create oauth access token
$token = $this->apiCaller->createAccessToken($username, $password);
if ($token === null) {
throw new CustomUserMessageAuthenticationException('Invalid username or password');
}
return new ApiToken($username, $token, $providerKey);
}
}
class ApiToken extends AbstractToken
{
private $token;
private $providerKey;
public function __construct($user, $token, $providerKey, array $roles = array())
{
parent::__construct($roles);
if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey must not be empty.');
}
$this->setUser($user);
$this->token = $token;
$this->providerKey = $providerKey;
parent::setAuthenticated(count($roles) > 0);
}
public function getAccessToken()
{
return $this->token->access_token;
}
public function getCredentials()
{
return $this->token;
}
public function getProviderKey()
{
return $this->providerKey;
}
}
class ApiUserProvider implements UserProviderInterface
{
private $apiCaller;
public function __construct($apiCaller)
{
$this->apiCaller = $apiCaller;
}
public function loadUserByUsername($accessToken)
{
$me = $this->apiCaller->me($accessToken);
return new ApiUser($me->username, $me->roles_unserialized);
}
public function refreshUser(UserInterface $user)
{
/*if (!$user instanceof WebserviceUser) {
throw new UnsupportedUserException(
sprintf('Instances of "%s" are not supported.', get_class($user))
);
}*/
return $this->loadUserByUsername($user->getUsername());
}
public function supportsClass($class)
{
return $class === 'AdminBundle\Security\ApiUser';
}
}
}
但是,我将始终重定向到登录。在logs / dev.log中有以下条目:
[2016-05-07 02:39:14] security.INFO: User has been authenticated successfully. {"username":"admin@foo.de"} []
[2016-05-07 02:39:14] security.DEBUG: Fallback to the default authentication success handler. [] []
[2016-05-07 02:39:14] security.DEBUG: Stored the security token in the session. {"key":"_security_admin"} []
[2016-05-07 02:39:15] request.INFO: Matched route "admin_dashboard". {"route_parameters":{"_controller":"AdminBundle\\Controller\\DashboardController::indexAction","_route":"admin_dashboard"},"request_uri":"http://admin.foo.dev/app_dev.php/"} []
[2016-05-07 02:02:42] security.INFO: An AuthenticationException was thrown; redirecting to authentication entry point. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AuthenticationCredentialsNotFoundException(code: 0): A Token was not found in the TokenStorage. at /var/www/foo-admin/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/AccessListener.php:53)"} []
任何人都可以帮助我吗?
最佳, 基督教
答案 0 :(得分:1)
如果我使用
session:
save_path: ~
而不是
session:
handler_id: session.handler.native_file
save_path: "%kernel.root_dir%/../var/sessions/%kernel.environment%"
用于会话处理,它按预期工作。任何人都知道,可能是什么问题?
答案 1 :(得分:0)
也许可以帮助文件.htaccess规则。
# Sets the HTTP_AUTHORIZATION header removed by Apache
RewriteCond %{HTTP:Authorization} .
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]