我是symfony的新手,我試圖獲得一個基於JWT的基本後衛身份驗證器。這項工作主要來自這裏的文章,我已經刪除了任何用戶檢查(現在):http://kolabdigital.com/lab-time/symfony-json-web-tokens-authentication-guardSymfony後衛:access_control沒有任何效果
我覺得有些東西我不明白,因爲我無法使它工作。更確切地說,即使在我實施的例外情況下,它在任何地方都可以工作。
這裏是檢查服務,基本相同的文章,沒有用戶管理,並且以位的日誌記錄:
<?php
namespace AppBundle\Security;
use Lexik\Bundle\JWTAuthenticationBundle\Encoder\DefaultEncoder;
use Lexik\Bundle\JWTAuthenticationBundle\TokenExtractor\AuthorizationHeaderTokenExtractor;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use Psr\Log\LoggerInterface;
class TokenAuthenticator extends AbstractGuardAuthenticator
{
private $jwtEncoder;
private $logger;
public function __construct(DefaultEncoder $jwtEncoder, LoggerInterface $logger)
{
$this->logger = $logger;
$this->jwtEncoder = $jwtEncoder;
}
public function start(Request $request, AuthenticationException $authException = null)
{
$route = $request->attributes->get('_route');
$url = $request->getUri();
$this->logger->info($route . ' : ' . $url);
return new JsonResponse('Authentication required', 401);
}
public function getCredentials(Request $request)
{
if(!$request->headers->has('Authorization')) {
return;
}
$extractor = new AuthorizationHeaderTokenExtractor(
'Bearer',
'Authorization'
);
$token = $extractor->extract($request);
if(!$token) {
return;
}
return $token;
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
$data = $this->jwtEncoder->decode($credentials);
if(!$data){
return;
}
$username = $data['username'];
// TODO get user from user collection
$user = ['username' => $username];
// Is user is encoded in token and exists, then it's fine
if(!$user){
return;
}
return $user;
}
public function checkCredentials($credentials, UserInterface $user)
{
return true;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
return new JsonResponse([
'message' => $exception->getMessage()
], 401);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
return;
}
public function supportsRememberMe()
{
return false;
}
}
而且security.yml,一切排除在外,只檢查行爲。
# To get started with security, check out the documentation:
# http://symfony.com/doc/current/security.html
security:
# http://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
providers:
in_memory:
memory: ~
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
#################################
# Secured section
#
# Custom authentication firewall for all request thats starts from /api
api:
pattern: ^/api
guard:
authenticators:
- app.token_authenticator
#################################
# Main Configuration
#
main:
anonymous: ~
# activate different ways to authenticate
# http_basic: ~
# http://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
# form_login: ~
# http://symfony.com/doc/current/cookbook/security/form_login_setup.html
access_control:
#- { path: ^/auth, roles: IS_AUTHENTICATED_ANONYMOUSLY }
#- { path: ^/version, roles: IS_AUTHENTICATED_ANONYMOUSLY }
#- { path: ^/api, roles: [ROLE_USER, ROLE_API_USER] }
- { path: ^/api, roles: IS_AUTHENTICATED_ANONYMOUSLY }
#- { path: ^/(css|js), roles: IS_AUTHENTICATED_ANONYMOUSLY }
#- { path: ^/(_wdt|_profiler), roles: IS_AUTHENTICATED_ANONYMOUSLY }
#- { path: ^/, roles: ROLE_USER }
我只是把後衛上^/API的地方,放一個control_access在同一路徑上允許匿名。我期望防護服務不會在具有該配置的任何路徑上調用,但每次都會調用它。我想我錯過了一些關於它如何工作的理解。 我的理解是:
- 訪問控制是任何事情之前
- 如果有一個匹配的行,它需要它(第一個)
- 如果IS_AUTHENTICATED_ANONYMOUSLY設置檢查,那麼防火牆不檢查
- 否則,下一個檢查是防火牆的配置,其中它告訴檢查與TokenAuthenticator
最初的目的是鎖定/api,除了/api/auth和/api /版本,可以無需控制地訪問。
感謝您的幫助,我認爲經過1天半的時間,我無法直截了當地思考。