Symfony 4 Rest API Token Verification вызывает метод запуска по умолчанию - PullRequest
0 голосов
/ 20 ноября 2018

https://symfony.com/doc/current/security/guard_authentication.html Согласно документации, функция запуска будет вызвана, если клиент получит доступ к URI / ресурсу, который требует аутентификации, но детали аутентификации не были отправлены, но я передал токен с запросом. Я не уверен, где я делаю что-то не так. Может кто-нибудь предложить мне .. Я много пытался искать, но все еще не мог найти решения.

Я также пытался напечатать токен по запросам, и он работал нормально ... поэтому я думаю, что проблема в чем-то другом, токен хорошо проходит с запросом.

если я изменю шаблон firewall - main - pattern на ^ / gateway / v1 /, это даст мне

Доступ запрещен, пользователь не полностью аутентифицирован; перенаправление на точку входа аутентификации.

Вывод моего журнала

 [Mon Nov 19 22:52:34 2018] 127.0.0.1:57773 [401]: /gateway/v1/products
2018-11-19T21:52:39+00:00 [info] Matched route "app_product_products".
2018-11-19T21:52:39+00:00 [debug] Checking for guard authentication credentials.
2018-11-19T21:52:39+00:00 [debug] Calling getCredentials() on guard authenticator.
2018-11-19T21:52:39+00:00 [info] An AuthenticationException was thrown; redirecting to authentication entry point.
2018-11-19T21:52:39+00:00 [debug] Calling Authentication entry point.
[Mon Nov 19 22:52:39 2018] 127.0.0.1:57777 [401]: /gateway/v1/products

TokenController -> Создать токен (http://127.0.0.1:8000/gateway/v1/token)

public function token(Request $request)
{


    $data =json_decode($request->getContent(),true);
    foreach ($this->getCustomers() as $customer){
        if($customer["username"]==$data['username'] && $customer["password"]==$data['password']){
           // $token = $this->tokenManager->create($customer["username"]);

           // $jwtManager = $this->container->get('lexik_jwt_authentication.jwt_manager');

            //                return new JsonResponse(['token' => $this->getRandomId()]);

           // $token = $this->get('lexik_jwt_authentication.jwt_manager')->create($user);

              $token = $this->get('lexik_jwt_authentication.encoder')->encode([
                      'username' => $customer["username"],
                      'role' => "IS_AUTHENTICATED_FULLY",
                      'exp' => time() + 3600 // 1 hour expiration
                  ]);
            //$User->setApiToken($token);

           return new JsonResponse(['token' => $token]);
        }
    }
    //return $response;
    return  $this->handleView("Customer Not Exits");
}

конфиг / пакеты / security.yaml

security:
# ...
#
#    encoders:
#        App\Security\Username:
#            algorithm: argon2i

firewalls:

    main:
        pattern:  ^/gateway/v1/token
        stateless: true
        anonymous: true
        json_login:
            check_path:               /gateway/v1/token
            success_handler:          lexik_jwt_authentication.handler.authentication_success
            failure_handler:          lexik_jwt_authentication.handler.authentication_failure

    api:
        pattern:   ^/gateway/v1/
        stateless: true
        guard:
            authenticators:
            - jwt_token_authenticator

access_control:
- { path: ^/gateway/v1/token, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/gateway/v1/,       roles: IS_AUTHENTICATED_FULLY }
providers:
    # used to reload user from session & other features (e.g. switch_user)
    app_user_provider:
        id: App\Security\UserProvider

ЦСИ / Безопасность / JwtTokenAuthenticator.php

<?php

namespace App\Security;

use Doctrine\ORM\EntityManager;
use Lexik\Bundle\JWTAuthenticationBundle\Encoder\JWTEncoderInterface;
use Lexik\Bundle\JWTAuthenticationBundle\Exception\JWTDecodeFailureException;
use Lexik\Bundle\JWTAuthenticationBundle\TokenExtractor\AuthorizationHeaderTokenExtractor;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;

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\HttpFoundation\Request;


class JwtTokenAuthenticator extends AbstractGuardAuthenticator
{

private $jwtEncoder;
private $em;

public function __construct(JWTEncoderInterface $jwtEncoder/*, EntityManager $em*/)
{
    $this->jwtEncoder = $jwtEncoder;
    /*$this->em = $em;*/
}

public function getCredentials(Request $request)
{
    $extractor = new AuthorizationHeaderTokenExtractor(
        'Bearer',
        'Authorization'
    );

    $token = $extractor->extract($request);
 //  return new JsonResponse($token);
    if (!$token) {
        return new JsonResponse("token not specified") ;
    }
    return $token;
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
    try {
        $data = $this->jwtEncoder->decode($credentials);
      //  return new JsonResponse($data);
    } catch (JWTDecodeFailureException $e) {
        throw new CustomUserMessageAuthenticationException('Invalid Token');
    }

    $username = $data['username'];
    //$role = $data['role'];
    //echo $role;
   // $user=new Username();
    //return $user->findbyusername($username);

     /*return true $this->em
        ->getRepository('AppBundle:User')
        ->findOneBy(['username' => $username]);*/

    return $userProvider->loadUserByUsername($username);
}
public function checkCredentials($credentials, UserInterface $user)
{
    return true;
    // TODO: Implement checkCredentials() method.
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
    $data = array(
        'message' => strtr($exception->getMessageKey(), $exception->getMessageData())

        // or to translate this message
        // $this->translator->trans($exception->getMessageKey(), $exception->getMessageData())
    );

    return new JsonResponse($data, Response::HTTP_FORBIDDEN);
    // TODO: Implement onAuthenticationFailure() method.
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
    return null;
    // TODO: Implement onAuthenticationSuccess() method.
}
public function supportsRememberMe()
{
    // TODO: Implement supportsRememberMe() method.
}
public function start(Request $request, AuthenticationException $authException = null)
{
    $data = array(
    // you might translate this message
    'message' => 'Authentication Required'
    );

    return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
    // TODO: Implement start() method.
}
public function supports(Request $request, AuthenticationException $authException = null)
{

    if ($request->getPathInfo() != '/gateway/v1/token') {
        return false;
    }
    /*
    return new JsonResponse([
        'error' => 'auth required'
    ], 401);

    echo "getCredential: ";
    $extractor = new AuthorizationHeaderTokenExtractor(
        'Bearer',
        'Authorization'
    );

    $token = $extractor->extract($request);
    if (!$token) {
        return new JsonResponse("token not specified") ;
    }
    return new JsonResponse($token);
    // TODO: Implement start() method.*/
}
}
...