Ich habe ein Symfony 2.8
Projekt, in dem ich FOSUserBundle
verwende. Die Authentifizierungsmethode FOSUser
verwendet die Tabelle fos_user
zum Identifizieren und Validieren der Anmeldeinformationen und des Schlüssels, der mit sha512
verschlüsselt wurde.FOSUserBundle mit zwei Authentifizierungsmethoden
Ist es möglich, einige Klassen zu ändern oder zu erweitern, so dass, falls es den Benutzer in der Tabelle fos_user
nicht findet, suchen Sie in der Benutzertabelle, in der der Schlüssel mit md5
verschlüsselt ist?
Aktualisierung nach dem Sonnenuntergang von madshvero:
ich eine Benutzerklasse erstellt haben:
namespace AppBundle\Security\User;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\EquatableInterface;
class WebserviceUser implements UserInterface, EquatableInterface
{
private $username;
private $password;
private $salt;
private $roles;
public function __construct($username, $password, $salt, array $roles)
{
$this->username = $username;
$this->password = $password;
$this->salt = $salt;
$this->roles = $roles;
}
public function getRoles()
{
return $this->roles;
}
public function getPassword()
{
return $this->password;
}
public function getSalt()
{
return $this->salt;
}
public function getUsername()
{
return $this->username;
}
public function eraseCredentials()
{
}
public function isEqualTo(UserInterface $user)
{
if (!$user instanceof WebserviceUser) {
return false;
}
if ($this->password !== $user->getPassword()) {
return false;
}
if ($this->salt !== $user->getSalt()) {
return false;
}
if ($this->username !== $user->getUsername()) {
return false;
}
return true;
}
}
Ich habe auch die Benutzer-Provider erstellt:
namespace AppBundle\Security\User;
use AppBundle\Security\User\WebserviceUser;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
class WebserviceUserProvider implements UserProviderInterface
{
public function loadUserByUsername($username)
{
// make a call to your webservice here
$userData = true;
// pretend it returns an array on success, false if there is no user
if ($userData) {
$username = 'prueba';
$password = 'e10adc3949ba59abbe56e057f20f883e'; // md5('123456')
$salt = '';`enter code here`
$roles = [ROLE_SUPER_ADMIN];
// ...
return new WebserviceUser($username, $password, $salt, $roles);
}
throw new UsernameNotFoundException(
sprintf('Username "%s" does not exist.', $username)
);
}
public function refreshUser(UserInterface $user)
{
if (!$user instanceof WebserviceUser) {
throw new UnsupportedUserException(
sprintf('Instances of "%s" are not supported.', get_class($user))
);
}
return $this->loadUserByUsername($user->getUsername());
}
public function supportsClass($class)
{
return WebserviceUser::class === $class;
}
}
Und modifiziere die security.yml:
Natürlich habe ich verändern auch den services.yml den Dienst app.webservice_user_provider hinzuzufügen: Dienstleistungen: app.form.group: Klasse: AppBundle \ Formular \ GroupFormType tags: - { Name: form.type, alias: app_group_registration}
app.form.user:
class: AppBundle\Form\ProfileFormType
tags:
- { name: form.type, alias: app_user_profile }
app.webservice_user_provider:
class: AppBundle\Security\User\WebserviceUserProvider
Dies getan, das Verhalten ist, dass das System den Zugriff für die Benutzer des fos_user Anbieter erlaubt, nicht aber für die Nutzer meines c ustom Anbieter. Was scheitert?
Das es das Protokoll:
[2017.02.16 11.37.08] request.INFO: Matched route "fos_user_security_check". { "Route_parameters": { "_ Controller": "AppBundle \ Controllers \ SecurityController :: checkAction", "_ Route": "fos_user_security_check"}, "request_uri": "http://127.0.0.1:8000/app_dev.php/login_check"} []
[2017-02-16 11:37:08] doctrine.DEBUG: SELECT t0.id_aspirante AS id_aspirante1, t0.correo AS correo2, t0.clave AS clave3, t0.status_cuenta AS status_cuenta4 FROM aspirantes2 t0 WHERE t0.correo = ? LIMIT 1 ["userFoo"] []
[2017-02-16 11:37:08] doctrine.DEBUG: SELECT t0.id_aspirante AS id_aspirante1, t0.correo AS correo2, t0.clave AS clave3, t0.status_cuenta AS status_cuenta4 FROM aspirantes2 t0 WHERE t0.correo = ? LIMIT 1 ["userFoo"] []
[2017-02-16 11:37:08] security.INFO: Authentication request failed. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AuthenticationServiceException(code: 0): The user provider must return a UserInterface object. at /home/userx/projects/myproj/vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/DaoAuthenticationProvider.php:94, Symfony\\Component\\Security\\Core\\Exception\\AuthenticationServiceException(code: 0): The user provider must return a UserInterface object. at /home/userx/projects/myproj/vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/DaoAuthenticationProvider.php:86)"} []
[2017-02-16 11:37:08] security.DEBUG: Authentication failure, redirect triggered. {"failure_path":"/login"} []
[2017-02-16 11:37:08] request.INFO: Matched route "fos_user_security_login". {"route_parameters":{"_controller":"AppBundle\\Controller\\SecurityController::loginAction","_route":"fos_user_security_login"},"request_uri":"http://127.0.0.1:8000/app_dev.php/login"} []
[2017-02-16 11:37:08] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
[2017-02-16 11:37:08] request.INFO: Matched route "_wdt". {"route_parameters":{"_controller":"web_profiler.controller.profiler:toolbarAction","token":"c368df","_route":"_wdt"},"request_uri":"http://127.0.0.1:8000/app_dev.php/_wdt/c368df"} []
[2017-02-16 11:37:08] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
[2017-02-16 11:37:08] security.DEBUG: Access denied, the user is not fully authenticated; redirecting to authentication entry point. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException(code: 403): Access Denied. at /home/userx/projects/myproj/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/AccessListener.php:70)"} []
[2017-02-16 11:37:08] security.DEBUG: Calling Authentication entry point. [] []
[2017-02-16 11:37:08] request.INFO: Matched route "fos_user_security_login". {"route_parameters":{"_controller":"AppBundle\\Controller\\SecurityController::loginAction","_route":"fos_user_security_login"},"request_uri":"http://127.0.0.1:8000/app_dev.php/login"} []
[2017-02-16 11:37:08] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
Hallo madshvero, danke für die Antwort so schnell. Ich möchte wirklich nicht meinen Provider anstelle von FOSUser verwenden, ich möchte, dass der Nutzer sich zuerst den FOSUser-Anbieter ansieht und ob er nicht in meinem sucht. –
Ist es eine Option, dass Ihr Provider den FOSUserBundle-Provider erweitert und zuerst überprüft, ob "parent :: loadUserByUsername" eine Ausnahme auslöst, und wenn ja, Ihre eigene Logik für die andere Tabelle verwendet? Sie könnten auch in Ihrem Provider den [user manager] (https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Model/UserManager.php) verwenden, der im [provider im FOSUserBundle] verwendet wird (https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Security/UserProvider.php) um die Benutzer zu sehen – madshvero