Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
243 views
in Technique[技术] by (71.8m points)

symfony5 - How to implement Symfony 5 Authentication without Doctrine?

Am in the process of rewriting an existing PHP project to Symfony 5.3. I want to upgrade its authentication system to Symfony's. Only issue: Doctrine is not an option in this project.

How can I use Symfony's authentication (possibly together with the new Authenticator-based Security) without invoking Doctrine anywhere?

I know that I must implement a UserLoaderInterface, but the docs use Doctrine so heavily that I cannot figure out how to do it without.

The post I just mentioned is asking something similar, but it still uses Symfony 2 and is thus too outdated.

I have a database that has the necessary User table with the usual columns (ID, eMail, Password, Name, etc.).

To the point: How can I use Symfony's authentication (possibly together with the new Authenticator-based Security) without Doctrine?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To configurate that is on the the official website and also on this tutorial in SymfonyCast, but basically you can authenticate the user as you want:

See the next example:

Create a file on srcAppSecurity folder if your configuration is using the default config and create the class TokenAuthenticator, now see the below code, in this case check the class AppServiceExternalAuthenticator, who will be in charge to get the information from other service or api and the return.

<?php

namespace AppSecurity;

use AppExampleStudent;
use AppServiceExternalAuthenticator;
use AppDTOINFORMATIONFROMOTHERSERVICE;
use SymfonyComponentHttpFoundationRedirectResponse;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentRoutingGeneratorUrlGeneratorInterface;
use SymfonyComponentSecurityCoreAuthenticationTokenTokenInterface;
use SymfonyComponentSecurityCoreExceptionAuthenticationCredentialsNotFoundException;
use SymfonyComponentSecurityCoreExceptionAuthenticationException;
use SymfonyComponentSecurityCoreUserUserInterface;
use SymfonyComponentSecurityCoreUserUserProviderInterface;
use SymfonyComponentSecurityGuardAbstractGuardAuthenticator;
use SymfonyComponentSecurityCoreSecurity;

final class TokenAuthenticator extends AbstractGuardAuthenticator
{
    /** @var Security */
    private $security;

    /** @var ExternalAuthenticator */
    private $externalAuthenticator;

    /** @var UrlGeneratorInterface */
    private $urlGenerator;

    public function __construct(
        Security $security,
        ExternalAuthenticator $externalAuthenticator
    ) {
        $this->security = $security;
        $this->externalAuthenticator = $externalAuthenticator;
    }

    /**
     * {@inheritDoc}
     */
    public function supports(Request $request)
    {
        //on this example, this guard must be using if on the request contains the word token
        $response = false;
        $apiKey = $request->query->get('token');
        if (!is_null($apiKey)) {
            $response = true;
        }

        return $response;
    }

    /**
     * {@inheritDoc}
     */
    public function getCredentials(Request $request)
    {
        $apiKey = $request->query->get('token');
        // Validate with anything you want, other service or api
        /** @var INFORMATIONFROMOTHERSERVICE**/
        $dtoToken = $this->externalAuthenticator->validateToken($apiKey, $simulator);

        return $dtoToken;
    }

    /**
     * @param INFORMATIONFROMOTHERSERVICE $credentials
     * @param UserProviderInterface $userProvider
     * @return INFORMATIONFROMOTHERSERVICE |UserInterface|null
     */
    public function getUser($credentials, UserProviderInterface $userProvider)
    {
        return $userProvider;
    }

    public function checkCredentials($credentials, UserInterface $user)
    {
        return true;
    }

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
    {
        return new RedirectResponse($this->urlGenerator->generate('home_incorrect'));
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey)
    {
        return new RedirectResponse($request->getPathInfo());
    }

    public function start(Request $request, AuthenticationException $authException = null)
    {
        return new RedirectResponse($this->urlGenerator->generate('home_incorrect'));
    }

    public function supportsRememberMe()
    {
        // todo
    }
}

Now the external service must return AppDTOINFORMATIONFROMOTHERSERVICE class, but this class must implement the UserInterface, now with this in mind. We need to configurate what guard must be in charge of what routes, see the next example:

security:
    encoders:
        AppEntityUser:
            algorithm: bcrypt

    # 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: AppEntityUser
                property: email
        //You can use a 
        custom_provider:
            id : AppDTOINFORMATIONFROMOTHERSERVICE
        # used to reload user from session & other features (e.g. switch_user)
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        survey:
            anonymous: true
            pattern: ^/(custom_path)/
            // The
            provider: custom_provider
            guard:
                // You can use as many authenticator that you want, but in the node entrypoint, you must choose who must be the default if only is one you could remove the entrypoint node, similar as the main firewall
                authenticators:
                    - AppSecurityTokenAuthenticator
                    - AppSecurityOtherAuthenticator
                entry_point: AppSecurityOtherAuthenticator
        main:
            anonymous: true
            lazy: true
            provider: app_user_provider
            logout:
                path: app_logout
            guard:
                authenticators:
                    - AppSecurityAppAuthenticator

Also see the next documentation, that will guide you to create the class AppDTOINFORMATIONFROMOTHERSERVICE.

I hope this answer, help you


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...