php - 如何访问 Sym2 FOSUserBundle 自定义 UserChecker 中的请求对象

标签 php symfony authentication fosuserbundle

我将 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/

相关文章:

php - https登录后续页面应该使用http吗?

forms - 使用 ManyToOne 进行验证

html - Silex Assets 文件

php - Python 中的 cURL 帮助

php - Symfony 3、Php 和 Ubuntu 16 无法上传大文件

symfony - Symfony2 transchoice标签

php - Facebook 登录重定向 PHP/Javascript 不起作用

authentication - 在没有模型的情况下使用 Guardian

php - 将分解数组转换为字符串

php - 通过 PHP 挂起生成 Crystal Report