Home > Software design >  How to authenticate route with JWT token?
How to authenticate route with JWT token?

Time:03-22

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 }

  1. Route '/authentication_token' : everyone is allowed access
  2. Route '/api/' : access is allowed only to authorized users (the role does not matter)
  3. 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.

  • Related