I am working on JWT Token authentication in symfony. After login, I have already got a valid token valid for 5 minutes.
What I need is mandatory pass Bearer TOKEN
in other routes.
I tried in Postman, without Authorization, it is giving me result.
How can I make the token mandatory for the routes.
These are the codes, I have tried.
TokenAuthenticator.php
class TokenAuthenticator extends AbstractGuardAuthenticator
{
public function __construct(
private string $jwtSecret,
private EntityManagerInterface $entityManager
) {
}
public function start(Request $request, AuthenticationException $authException = null): JsonResponse
{
$data = [
'message' => 'Authentication Required'
];
return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
}
public function supports(Request $request): bool
{
return $request->headers->has('Authorization');
}
public function getCredentials(Request $request)
{
return $request->headers->get('Authorization');
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
try {
$credentials = str_replace('Bearer ', '', $credentials);
$decodedJwt = (array) JWT::decode(
$credentials,
new Key($this->jwtSecret, 'HS256')
);
return $this->entityManager
->getRepository(User::class)
->findOneBy([
'username' => $decodedJwt['user'],
]);
} catch (Exception $exception) {
throw new AuthenticationException($exception->getMessage());
}
}
public function checkCredentials($credentials, UserInterface $user): bool
{
return true;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): JsonResponse
{
return new JsonResponse([
'message' => $exception->getMessage()
], Response::HTTP_UNAUTHORIZED);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey)
{
return;
}
public function supportsRememberMe(): bool
{
return false;
}
}
security.yaml
security:
enable_authenticator_manager: true
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
encoders:
App\Entity\User:
algorithm: bcrypt
providers:
user_provider:
entity:
class: App\Entity\User
property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
lazy: true
provider: user_provider
pattern: ^/api
guard:
authenticators:
- App\Security\TokenAuthenticator
logout:
path: api_logout
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
Can anybody help me, what I am missing ?
CodePudding user response:
You can restrict access to routes in the security.yaml
file by declaring your route in access_control
with the IS_AUTHENTICATED_FULLY
parameter.
Example:
access_control:
- { path: ^/authentication_token, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/admin/, roles: ROLE_ADMIN }
- Route
'/authentication_token'
: everyone is allowed access - Route
'/api/'
: access is allowed only to authorized users (the role does not matter) - Route
'/admin/'
: access is allowed only to authorized users with the ROLE_ADMIN role
Note: This is described in more detail in the official symfony documentation.