Two-way authentication in a Symfony 2 project

I need to implement a two-way authentication process in one of my Symfony 2 projects according to this algorithm:

  • The user enters his username and password in the authentication form and sends it.
  • First, the system checks its default username and password (all users are stored in Doctrine ORM).
  • If the previous step failed, calling the external API and passing it the username and md5(password).
  • If the previous step was successful, create a new user object and use it as an authenticated user.
  • If step 3 fails, authentication is considered unsuccessful.

I already have a service that can be called to authenticate a user with a username and password using an external API, I'm just looking for a way to use it in the authentication process.

What is the easiest way to implement this behavior? I just have to be directed in the right direction.

Update

Does ' user authenticator' is a good solution to this problem? Or is there a better approach?

If you look at the documentation, I will have to implement both authentication steps in my custom authenticator. Is it possible to implement only an additional step?

+4
source share
1 answer

, . - , UserProvider, . un/pw, , . , .

public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
{
    try {
        $user = $userProvider->loadUserByUsername($token->getUsername());
    } catch (UsernameNotFoundException $e) {
        throw new AuthenticationException('Invalid username or password');
    }

    $encoder = $this->encoderFactory->getEncoder($user);
    $passwordValid = $encoder->isPasswordValid(
        $user->getPassword(),
        $token->getCredentials(),
        $user->getSalt()
    );

    if ($passwordValid) {

        return new UsernamePasswordToken(
            $user,
            $user->getPassword(),
            $providerKey,
            $user->getRoles()
        );
    }

    // remote users fallback

    $webUser = $this->externalUserService->getByUsernamePassword(
        $token->getUsername(),
        $token->getCredentials()

    );

    if ($webUser) {
        return new UsernamePasswordToken(
            $webUser,
            $token->getCredentials(),
            $providerKey,
            $webUser->getRoles()
        );
    }

    throw new AuthenticationException('Invalid username or password');
}

Ofc ifs , , , , 3 , , db- , .

# services.yml

my_app.authenticator.main:
    class: MyApp/Security/Core/Authentication/CompisiteAuthenticator
    calls:
        - [ add, [@my_app.authenticator.locale]]
        - [ add, [@my_app.authenticator.remote]]

my_app.authenticator.locale:
    class: MyApp/Security/Core/Authentication/LocalAuthenticator
    arguments: [@security.encoder_factory]

my_app.authenticator.remote:
    class: MyApp/Security/Core/Authentication/RemoteAuthenticator
    arguments: [@my_app.remote_user_service]

<?php

namespace MyApp/Security/Core/;

class CompositeAuthenticator implements SimpleFormAuthenticatorInterface
{
    /** @var SimpleFormAuthenticatorInterface[] */
    protected $children = array();

    public function add(SimpleFormAuthenticatorInterface $authenticator)
    {
        $this->children[] = $authenticator;
    }

    public function createToken(Request $request, $username, $password, $providerKey)
    {
        return new UsernamePasswordToken($username, $password, $providerKey);
    }

    public function supportsToken(TokenInterface $token, $providerKey)
    {
        return $token instanceof UsernamePasswordToken
            && $token->getProviderKey() === $providerKey;
    }

    public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
    {
        $result = null;
        foreach ($this->children as $authenticator)
        {
            $result = $authenticator->authenticateToken($token, $userProvider, $providerKey);
            if ($result) {

                return $result;
            }
        }

        throw new AuthenticationException('Invalid username or password');
    }
}

0

Source: https://habr.com/ru/post/1543454/


All Articles