所以我使用Guard Authenticators对用户进行身份验证。
登录和注销成功,但是当我尝试在其他路由上请求时,它会抛出AuthenticationCredentialsNotFoundException说
在TokenStorage中找不到令牌。
因此,回应401。
这是我的身份验证员类:
class ApiAuthenticator extends AbstractGuardAuthenticator implements LogoutSuccessHandlerInterface
{
public function getCredentials(Request $request)
{
if ($request->getPathInfo() != '/login' || !$request->isMethod('POST')) {
return;
}
$data = json_decode($request->getContent(), true);
return [
'username' => $data['_username'],
'password' => $data['_password'],
];
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
return $userProvider->loadUserByUsername($credentials);
}
public function checkCredentials($credentials, UserInterface $user)
{
if (!$user instanceof User) {
throw new \TypeError();
}
return true;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
return new JsonResponse([ 'error' => 'Invalid Credentials!'], Response::HTTP_UNAUTHORIZED); }
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
$response = [
'success' => 'Success!',
'customer' => [
'name' => 'Fullname',
'memberSince' => 'mm/dd/yyyy'
]
];
return new JsonResponse($response, Response::HTTP_OK);
}
public function start(Request $request, AuthenticationException $authException = null)
{
return new Response('', Response::HTTP_UNAUTHORIZED);
}
public function supportsRememberMe()
{
}
public function onLogoutSuccess(Request $request)
{
$request->getSession()->invalidate();
return new Response();
}
}
这是我的UserProvider类:
class UserProvider implements UserProviderInterface
{
private $apiHelper;
private $session;
public function __construct(ApiHelper $apiHelper, Session $session)
{
$this->apiHelper = $apiHelper;
$this->session = $session;
}
public function loadUserByUsername($credentials)
{
$response = $this->apiHelper->generateAccessToken($credentials['username'], $credentials['password']);
if (isset($response['access_token'])) {
$this->session->set('authAccessToken', $response['access_token']);
$this->session->set('authExpiresIn', $response['expires_in']);
$this->session->set('authRefreshToken', $response['refresh_token']);
$accessToken = new AccessToken();
$accessToken->setAccessToken($response['access_token']);
$accessToken->setExpiresIn($response['expires_in']);
$accessToken->setTokenType($response['token_type']);
$accessToken->setScope($response['scope']);
$accessToken->setRefreshToken($response['refresh_token']);
return new User($accessToken);
}
throw new UsernameNotFoundException(
sprintf('Username "%s" does not exist.', '')
);
}
public function refreshUser(UserInterface $user)
{
if (!$user instanceof User) {
throw new UnsupportedUserException(
sprintf('Instances of "%s" are not supported.', get_class($user))
);
}
return $user;
// return $this->loadUserByUsername([
// 'password' => $user->getPassword(),
// 'username' => $user->getUsername(),
// ]);
}
public function supportsClass($class)
{
return User::class === $class;
}
}
这是我的security.yml
security:
providers:
user_provider:
id: user_provider
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
http_basic: ~
pattern: ^/
provider: user_provider
logout:
path: /logout
success_handler: api_authenticator
guard:
authenticators:
- api_authenticator
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/test, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: IS_AUTHENTICATED_FULLY }
谢谢!
答案 0 :(得分:0)
尝试实现AuthenticationFailureHandlerInterface
并在onAuthenticationFailure
中引发异常。
答案 1 :(得分:0)
添加
main:
# ...
anonymous: true
# ...
到 security.yml 将有助于将该异常转换为 AccessDeniedException(通常应该在开发模式下转换为 InsufficientAuthenticationException 并重定向到登录在 prod 模式下使用内核异常侦听器,但这取决于您)。