我将 Synfony2 与 FOSUserBundle 一起使用,我有一个自定义的 userChecker,我想在其中验证用户的主机(我们有多个主机指向同一个 IP)。我的问题是在我的自定义 userChecker 中我无法访问 REQUEST,因此无法访问请求的 HOST。
这是我的用户验证码
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
//Override by Mattias
namespace BizTV\UserBundle\Controller;
//namespace Symfony\Component\Security\Core\User;
use Symfony\Component\Security\Core\Exception\CredentialsExpiredException;
use Symfony\Component\Security\Core\Exception\LockedException;
use Symfony\Component\Security\Core\Exception\DisabledException;
use Symfony\Component\Security\Core\Exception\AccountExpiredException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserChecker as OriginalUserChecker;
use Symfony\Component\HttpFoundation\Request as Request; //ADDED BY MW
/**
* UserChecker checks the user account flags.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class UserCheckerNew extends OriginalUserChecker
{
/**
* {@inheritdoc}
*/
public function checkPreAuth(UserInterface $user)
{
/*
//Test for companylock...
if ( !$user->getCompany()->getActive() ) {
throw new LockedException('The company of this user is locked.', $user);
}
if ( $user->getLocked() ) {
throw new LockedException('The admin of this company has locked this user.', $user);
}
*/
if (!$user instanceof AdvancedUserInterface) {
return;
}
if (!$user->isCredentialsNonExpired()) {
throw new CredentialsExpiredException('User credentials have expired.', $user);
}
}
/**
* {@inheritdoc}
*/
public function checkPostAuth(UserInterface $user)
{
//Test for companylock...
if ( !$user->getCompany()->getActive() ) {
throw new LockedException('The company of this user is locked.');
}
if ( $user->getLocked() ) {
throw new LockedException('The admin of this company has locked this user.');
}
/*
Validate HOST here
*/
if (!$user instanceof AdvancedUserInterface) {
return;
}
if (!$user->isAccountNonLocked()) {
throw new LockedException('User account is locked.', $user);
}
if (!$user->isEnabled()) {
throw new DisabledException('User account is disabled.', $user);
}
if (!$user->isAccountNonExpired()) {
throw new AccountExpiredException('User account has expired.', $user);
}
}
}
在 checkPostAuth 函数中,我尝试了不同的方法,比如传递请求
public function checkPostAuth(UserInterface $user, Request $request)
错误说我的覆盖必须符合原始/接口(interface)。
尝试在 Controller 中获取请求
$this->container->get('request_stack')->getCurrentRequest();
或者像这样
$currentHost = $request->getHost();
或者像这样
$cont = $this->getContainer();
或者像这样
$request = $this->getRequest();
或者像这样
$request = $container->get('request');
但运气不佳 =) 我不是 Symfony2 专家,如你所知,我在这里从臀部射击 =)
根据gp-sflover的回答给config.yml添加了参数,我的config.yml现在是这样的:
services:
security.user_checker:
class: BizTV\UserBundle\Controller\UserCheckerNew
arguments: [ "@request" ]
scope: request
public: true
在将 scope:request 添加到配置之前传递的错误是:
Scope Widening Injection detected: The definition "security.user_checker" references the service "request" which belongs to a narrower scope. Generally, it is safer to either move "security.user_checker" to scope "request" or alternatively rely on the provider pattern by injecting the container itself, and requesting the service "request" each time it is needed. In rare, special cases however that might not be necessary, then you can set the reference to strict=false to get rid of this error.'
添加scope: request时返回一个非常相似的错误
Scope Widening Injection detected: The definition "security.authentication.provider.dao.main" references the service "security.user_checker" which belongs to a narrower scope. Generally, it is safer to either move "security.authentication.provider.dao.main" to scope "request" or alternatively rely on the provider pattern by injecting the container itself, and requesting the service "security.user_checker" each time it is needed. In rare, special cases however that might not be necessary, then you can set the reference to strict=false to get rid of this error
添加 public: true 似乎没有什么不同。另外,我不知道这个 public 东西的真正含义,也许是安全问题?公共(public)这个词总是很可怕 =)
最佳答案
您可以覆盖 security.user_checker
服务,而不是扩展“OriginalUserChecker”类,以便能够将 request_stack
作为参数注入(inject),然后在您的 中检索它>UserChecker
类就像这个简单的例子:
服务.xml
// Symfony >=2.6
<service id="security.user_checker"
class="Your\Bundle\Path\ToYour\UserCheckerClass">
<argument type="service" id="request_stack"/>
</service>
// Symfony <2.6
<service id="security.user_checker"
class="Your\Bundle\Path\ToYour\UserCheckerClass">
<argument type="service" id="request" public="true" scope="request"/>
</service>
UserCheckerClass
use Symfony\Component\Security\Core\User\UserCheckerInterface;
// Symfony >=2.6
use Symfony\Component\HttpFoundation\RequestStack;
// Symfony <2.6
use Symfony\Component\HttpFoundation\Request;
class UserChecker implements UserCheckerInterface
{
private $request;
public function __construct(
// Symfony >=2.6
RequestStack $request
// Symfony <2.6
Request $request
) {
$this->request = $request;
}
public function checkPreAuth(UserInterface $user)
{
// your checks here
}
public function checkPostAuth(UserInterface $user)
{
// your checks here
}
}
关于php - 如何访问 Sym2 FOSUserBundle 自定义 UserChecker 中的请求对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32457147/