Symfony 5 - программная аутентификация по идентификатору пользователя - PullRequest
0 голосов
/ 21 апреля 2020

Привет, я работаю над программной аутентификацией в моей системе Symfony5:

Я проверил довольно много сообщений о stackoverflow, но ни одно из них не решило мою проблему. Большинство из них не относятся к Symfony 5, но более старые версии - фреймворк систематически развивается. Поэтому я решил задать вопрос.

Предположим, у меня очень хорошо защищенная конечная точка:

$api = new UserApiClient();
$result = $api->getUser($request->query->get('token'));

if(!$request->query->get('token') or (isset($result['code']) and $result['code'] == 401)){
    throw new \Exception('Login failed');
}

$user = $this->getDoctrine()->getRepository('App\Entity\Users\User')->find($result['id']);

$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$authenticatedToken = $authenticationManager->authenticate($token);
$tokenStorage->setToken($authenticatedToken);

Конечно, приведенный выше код не работает. Вот журналы моей системы:

[2020-04-21T06:49:15.157022+00:00] request.INFO: Matched route "user_api_login". {"route":"user_api_login","route_parameters":{"_route":"user_api_login","_controller":"App\\Controller\\UserAPIController::index"},"request_uri":"https://my.domain.com/user-api/login?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1ODc0NDg3ODIsImV4cCI6MTU4NzQ1MjM4Miwicm9sZXMiOlsiUk9MRV9TVVBFUl9BRE1JTiIsIlJPTEVfVVNFUiJdLCJ1c2VybmFtZSI6ImFkbWluQGl0Y2VudGVyLnBsIn0.IcqZs8-o38NgKUXKwaiGRSw-mC8T6gRvtBvMpnioXAf9ueQV_1jFJ530WmQ7O59Tqs-kLR3ce3dxvsR_QLniF8s5QLBTWyPI4zrmZLU9ERCVwgE-CVrF-ag8b8fRDeEkxfa2H18Unzo2y_xvmxKUE7aeHrCXm6QQ7Uk_sEJg-osvo61Qfi5JJEjSgzcCa8W71mMY8W07CVxoKCChoiDDnj3dp7VqbvMkWJGJBoMAjnlfFyV26FH2h6F9rb_bxAVB_2lk4M7Q43vrbdeexKKcKcvKASEBX28K8zI05qRQZNRGfgTxofW8hHXOQDnZgaHm3dkh1C2rlOV61rJewhrXB8n9z0Jwhn1qkoxI_p3O6i-TveFWZD0uOjsiOCvUb1yifsMFMTYzmJTPf03thGIfF833uDJZ9UhZFHp7mW422jgmAOLWIqD6ah8E1uvasGidEiLZRZpd7tvvAdA2NmpTIFJylgXlj-e2qlzZcnCZTNeKstTH0Y06b7nmQBcvRJL2A8xCTQFEvTAQScB-IiWwQTy6fQ5luUhjLhi40PW7H6zraLm6TeEdEY_19mHWPfFE_E8s9IyhLRZg9alhuTqQGQnAAYfa-_wk9CXoXexIE36Uj4r22FMixKwTSWWNKPxXT5EYQmsA8riv9HhCo2GWuzCwCBta2p8K9Sy6iiCNKKQ","method":"GET"} []
[2020-04-21T06:49:15.192344+00:00] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"main","authenticators":1} []
[2020-04-21T06:49:15.192468+00:00] security.DEBUG: Checking support on guard authenticator. {"firewall_key":"main","authenticator":"App\\Security\\LoginFormAuthenticator"} []
[2020-04-21T06:49:15.192628+00:00] security.DEBUG: Guard authenticator does not support the request. {"firewall_key":"main","authenticator":"App\\Security\\LoginFormAuthenticator"} []
[2020-04-21T06:49:15.201915+00:00] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
[2020-04-21T06:49:15.545055+00:00] doctrine.DEBUG: SELECT t0.id AS id_1, t0.email AS email_2, t0.roles AS roles_3, t0.password AS password_4, t0.parent AS parent_5, t0.data AS data_6 FROM user t0 WHERE t0.id = ? [1] []
[2020-04-21T06:49:15.569395+00:00] security.INFO: An AuthenticationException was thrown; redirecting to authentication entry point. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\ProviderNotFoundException(code: 0): No Authentication Provider found for token of class \"Symfony\\Component\\Security\\Core\\Authentication\\Token\\UsernamePasswordToken\". at /home/budmechzz/public_html/my.domain.com/vendor/symfony/security-core/Authentication/AuthenticationProviderManager.php:108)"} []
[2020-04-21T06:49:15.569575+00:00] security.DEBUG: Calling Authentication entry point. [] []
[2020-04-21T06:49:15.780056+00:00] request.INFO: Matched route "app_login". {"route":"app_login","route_parameters":{"_route":"app_login","_controller":"App\\Controller\\SecurityController::login"},"request_uri":"https://my.domain.com/login","method":"GET"} []
[2020-04-21T06:49:15.819083+00:00] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"main","authenticators":1} []
[2020-04-21T06:49:15.819198+00:00] security.DEBUG: Checking support on guard authenticator. {"firewall_key":"main","authenticator":"App\\Security\\LoginFormAuthenticator"} []
[2020-04-21T06:49:15.819253+00:00] security.DEBUG: Guard authenticator does not support the request. {"firewall_key":"main","authenticator":"App\\Security\\LoginFormAuthenticator"} []
[2020-04-21T06:49:15.833043+00:00] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
[2020-04-21T06:49:16.205043+00:00] request.INFO: Matched route "translation". {"route":"translation","route_parameters":{"_route":"translation","_controller":"App\\Controller\\TranslationController::index"},"request_uri":"https://my.domain.com/translation.js","method":"GET"} []
[2020-04-21T06:49:16.235087+00:00] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"main","authenticators":1} []
[2020-04-21T06:49:16.235195+00:00] security.DEBUG: Checking support on guard authenticator. {"firewall_key":"main","authenticator":"App\\Security\\LoginFormAuthenticator"} []
[2020-04-21T06:49:16.235265+00:00] security.DEBUG: Guard authenticator does not support the request. {"firewall_key":"main","authenticator":"App\\Security\\LoginFormAuthenticator"} []
[2020-04-21T06:49:16.260509+00:00] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
[2020-04-21T06:49:16.461603+00:00] request.INFO: Matched route "_wdt". {"route":"_wdt","route_parameters":{"_route":"_wdt","_controller":"web_profiler.controller.profiler::toolbarAction","token":"f7d69f"},"request_uri":"https://my.domain.com/_wdt/f7d69f","method":"GET"} []

Эта строка может указывать причину ошибки:

[2020-04-21T07:36:55.884254+00:00] security.INFO: An AuthenticationException was thrown; redirecting to authentication entry point. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\ProviderNotFoundException(code: 0): No Authentication Provider found for token of class \"Symfony\\Component\\Security\\Core\\Authentication\\Token\\UsernamePasswordToken\". at /home/budmechzz/public_html/rfm.computermedia.com.pl/vendor/symfony/security-core/Authentication/AuthenticationProviderManager.php:108)"} []

Но в моем случае провайдер аутентификации выглядит настроенным правильно. Вот мой security.yaml:

security:
    encoders:
        App\Entity\Users\User:
            algorithm: argon2i

    # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
    providers:
        # used to reload user from session & other features (e.g. switch_user)
        app_user_provider:
            entity:
                class: App\Entity\Users\User
                property: email
                manager_name: users
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            anonymous: lazy
            provider: app_user_provider
            guard:
                authenticators:
                    - App\Security\LoginFormAuthenticator
            logout:
                path: app_logout
                # where to redirect after logout
                # target: app_any_route

            # activate different ways to authenticate
            # https://symfony.com/doc/current/security.html#firewalls-authentication

            # https://symfony.com/doc/current/security/impersonating_user.html
            # switch_user: true

    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
        # - { path: ^/admin, roles: ROLE_ADMIN }
        # - { path: ^/profile, roles: ROLE_USER }

@ NicoHaase - спасибо, что помогли мне увидеть исключение

1 Ответ

0 голосов
/ 21 апреля 2020

Хорошо, спасибо за поддержку Symfony и эту статью я решаю свою проблему: https://symfonycasts.com/screencast/symfony-security/registration-auth

Я не совсем понял эту проблему, но после прочтения вышеупомянутой статьи все стало ясно. Вот мой контроллер:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use App\Utils\UserApiClient;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
use App\Security\LoginFormAuthenticator;

/**
 * This is main User API controller.
 * 
 * @Route("/user-api")
 */
class UserAPIController extends AbstractController
{

    /**
     * @Route("/login", name="user_api_login")
     */
    public function index(Request $request, GuardAuthenticatorHandler $guardHandler, LoginFormAuthenticator $formAuthenticator)
    {

        if($this->getUser()){
            return $this->redirectToRoute('cockpit');
        }

        $api = new UserApiClient();
        $result = $api->getUser($request->query->get('token'));

        if(!$request->query->get('token') or (isset($result['code']) and $result['code'] == 401)){
            throw new \Exception('Login failed');
        }

        $this->get('session')->set('api_token', $request->query->get('token'));
        $user = $this->getDoctrine()->getRepository('App\Entity\Users\User')->find($result['id']);

        return $guardHandler->authenticateUserAndHandleSuccess(
            $user,
            $request,
            $formAuthenticator,
            'main'
        );

    }
}

Надеюсь это кому-нибудь пригодится:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...