• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Symfony - autentykacja na predefiniowanej bazie danych

Object Storage Arubacloud
0 głosów
119 wizyt
pytanie zadane 13 kwietnia 2020 w SQL, bazy danych przez XiverKi Bywalec (2,050 p.)

dzień dobry,

postanowiłem pobawić się z integracją symfony do bazy, która jest już stowrzona, ma swoja strukture, klucze itd.

Utworzyłem sobie encje za pomocą tego narzedzia:

php bin/console doctrine:mapping:port "App\Entity" annotation --path=src/Entity

Wszystko jest w porządku, udało mi się zrobić rejestracje i inne bajerki.

Zatrzymałem się jednak na logowaniu. 

Co prawda po kilku szpachlach i kombinacjach udało mi się to zrobić ale:

  1. Musiałem dodać nowe pole do tabeli, w której trzymam użytkowników. 
  2. Dodać nowy własny encoder sha1 - takie kodowanie wymagane jest przez aplikacje używającą bazy.

Mój encoder wygląda tak:

<?php


namespace App\Security;

use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;

class Sha1PasswordEncoder implements PasswordEncoderInterface
{

    /**
     * @inheritDoc
     */
    public function encodePassword(string $raw, ?string $salt)
    {
        return sha1($raw);
    }

    /**
     * @inheritDoc
     */
    public function isPasswordValid(string $encoded, string $raw, ?string $salt)
    {
        return sha1($raw) == $encoded;
    }

    /**
     * @inheritDoc
     */
    public function needsRehash(string $encoded): bool
    {
        // TODO: Implement needsRehash() method.
    }
}

 

Natomiast to jest mój authentykator:

<?php

namespace App\Security;

use App\Entity\Accounts;
use App\Repository\AccountsRepository;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
use Symfony\Component\Security\Http\Util\TargetPathTrait;

class LoginAuthenticator extends AbstractFormLoginAuthenticator
{
    use TargetPathTrait;


    /**
     * @var AccountsRepository
     */
    private $accountsRepository;
    /**
     * @var CsrfTokenManagerInterface
     */
    private $csrfTokenManager;
    /**
     * @var Sha1PasswordEncoder
     */
    private $passwordEncoder;
    /**
     * @var RouterInterface
     */
    private $router;

    public function __construct(AccountsRepository $accountsRepository, CsrfTokenManagerInterface $csrfTokenManager, Sha1PasswordEncoder $passwordEncoder, RouterInterface $router)
    {
        $this->accountsRepository = $accountsRepository;
        $this->csrfTokenManager = $csrfTokenManager;
        $this->passwordEncoder = $passwordEncoder;
        $this->router = $router;
    }

    public function supports(Request $request)
    {
        return $request->attributes->get('_route') === 'app_login'
            && $request->isMethod('POST');
    }

    public function getCredentials(Request $request)
    {
        $credentials = [
            'login' => $request->request->get('login'),
            'password' => $request->request->get('password'),
            'csrf_token' => $request->request->get('_csrf_token'),
        ];

        $request->getSession()->set(
            Security::LAST_USERNAME,
            $credentials['login']
        );

        return $credentials;
    }

    public function getUser($credentials, UserProviderInterface $userProvider)
    {
        $token = new CsrfToken('authenticate', $credentials['csrf_token']);
        if (!$this->csrfTokenManager->isTokenValid($token)) {
            throw new InvalidCsrfTokenException();
        }

        return $this->accountsRepository->findOneBy([
            'name' => $credentials['login'],
        ]);
    }

    public function checkCredentials($credentials, UserInterface $user)
    {
        return $this->passwordEncoder->isPasswordValid(
            $this->passwordEncoder->encodePassword($credentials['password'], null),
            $credentials['password'],
            null
        );
    }
    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
    {
        if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
            return new RedirectResponse($targetPath);
        }

        return new RedirectResponse($this->router->generate('app_homepage'));
    }

    public function supportsRememberMe()
    {
        return false;
    }

    protected function getLoginUrl()
    {
        return $this->router->generate('app_login');
    }
}

 

A tu kontroler:

    /**
     * @Route("/login", name="app_login")
     */
    public function login(AuthenticationUtils $authenticationUtils)
    {
        // get the login error if there is one
        $error = $authenticationUtils->getLastAuthenticationError();

        // last username entered by the user
        $lastUsername = $authenticationUtils->getLastUsername();

        return $this->render('security/login.html.twig', [
            'last_username' => $lastUsername,
            'error'         => $error,
        ]);
    }

 

Wszystko działa poprawnie, użytkownik jest logowany, toolbar pokazuje poprawną autentykację.

 

Jednakże, moje pytanie brzmi. Co mogę zrobić aby pole roles wywalić do osobnej tabeli? Niestety koliduje ono z kodem gry, który wykorzystuje tą baze. Dodatkowo chciałbym się dowiedzieć czy wszystko wykonałem poprawnie i zgodnie ze sztuką.

 

Pozdrawiam

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
0 odpowiedzi 126 wizyt
0 głosów
1 odpowiedź 214 wizyt
0 głosów
0 odpowiedzi 89 wizyt
pytanie zadane 7 kwietnia 2019 w PHP przez michal_php Stary wyjadacz (13,700 p.)

92,567 zapytań

141,420 odpowiedzi

319,616 komentarzy

61,953 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...