我正在研究简单应用程序,该应用程序为两种用户,用户和管理实体处理身份验证。我想为我的安全性提供两个单独的防火墙和提供商。
security:
encoders:
AuthentificationBundleEntityuser:
Algorithm:bcrypt
AuthentificationBundleEntityAdmin:
Algorithm:bcrypt
role_hierarchy:
ROLE_USER: [ROLE_USER]
ROLE_ADMIN: [ROLE_ADMIN,ROLE_USER]
ROLE_SUPER_ADMIN: [ROLE_SUPER_ADMIN,ROLE_ADMIN,ROLE_USER]
providers:
users:
entity:
class: AuthentificationBundle:user
administrateur:
entity:
class: AuthentificationBundle:Admin
firewalls:
user_area:
pattern: ^/login
#anonymous: ~
form_login:
login_path: login
check_path: login_check
success_handler: after_login_redirection
logout:
path: logout
target: login
provider: users
admin_area:
pattern: ^/administration
#anonymous: ~
form_login:
login_path: login_admin
check_path: admin_login_check
success_handler: after_login_redirection
logout:
path: /logout
target: /administration
provider: administrateur
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/administration, roles: ROLE_ADMIN }
我是由fosuserbundle启发的自己的提供商。
基本上,我为提供商提供了服务,并将其设置为这样:
providers:
admins:
id: user_provider.admins
users:
id: user_provider.users
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
admin_secured_area:
host: "%admin_host%"
pattern: ^/*
form_login:
provider: admins
login_path: /login
check_path: /login_check
csrf_token_generator: security.csrf.token_manager
logout:
path: /logout
target: /
anonymous: true
users_secured_area:
host: "%users_host%"
pattern: ^/*
form_login:
provider: users
login_path: /login
check_path: /login_check
csrf_token_generator: security.csrf.token_manager
logout:
path: /logout
target: /
anonymous: true
然后是我的提供商类,它是名为user_provider.admins
<?php
namespace APPAppBundleSecurity;
use ...;
class AdminsProvider extends AbstractUserProvider
{
/** @var Admins */
protected $userClass;
/** @var Admins */
protected $repositoryClass;
/**
* @inheritdoc
*/
public function setUserClass()
{
$this->userClass = Admins::class;
}
/**
* @return Admins
*/
public function getUserClass()
{
return $this->userClass;
}
/**
* @inheritdoc
*/
public function setUserRepository()
{
$this->repositoryClass = Admins::class;
}
/**
* @return Admins
*/
public function getUserRepository()
{
return Admins::class;
}
}
和抽象的用户提供商最终将示例
<?php
namespace AppAppBundleSecurity;
use ...;
abstract class AbstractUserProvider implements UserProviderInterface
{
/**
* @var EntityManager
*/
protected $em;
/**
* UserProvider constructor.
*
* @param EntityManager $em
*/
public function __construct(EntityManager $em)
{
$this->em = $em;
}
/**
* @return mixed
*/
abstract protected function setUserRepository();
/**
* @return mixed
*/
abstract protected function getUserRepository();
/**
* @return mixed
*/
abstract protected function setUserClass();
/**
* @return mixed
*/
abstract protected function getUserClass();
/**
* {@inheritDoc}
*/
public function loadUserByUsername($username)
{
$oUser = $this->em->getRepository($this->getUserRepository())->findOneByUsername($username);
if (!$oUser) {
throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username));
}
return $oUser;
}
/**
* {@inheritDoc}
*/
public function refreshUser(UserInterface $oUser)
{
if (!$this->supportsClass(get_class($oUser))) {
throw new UnsupportedUserException(sprintf('Expected an instance of %s, but got "%s".', get_class($this->getUserClass()), get_class($oUser)));
}
if (null === $reloadedUser = $this->em->getRepository($this->getUserRepository())->findOneById($oUser->getId())
) {
throw new UsernameNotFoundException(sprintf('User with ID "%s" could not be reloaded.', $oUser->getId()));
}
return $reloadedUser;
}
/**
* {@inheritDoc}
*/
public function supportsClass($class)
{
$userClass = $this->getUserRepository();
return $userClass === $class || is_subclass_of($class, $userClass);
}
}