Php Symfony FOS OAuth和自定义用户

Php Symfony FOS OAuth和自定义用户,php,symfony,oauth,oauth-2.0,fosoauthserverbundle,Php,Symfony,Oauth,Oauth 2.0,Fosoauthserverbundle,如何在不使用FOSUserBundle的情况下实现基于FOSOAuthServerBundle的OAuth服务器 我的用户类开始时与他的类似: <?php namespace AppBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\UserInterface; /** * * @ORM\Entity * @ORM\Table(name="user") * @

如何在不使用FOSUserBundle的情况下实现基于FOSOAuthServerBundle的OAuth服务器

我的用户类开始时与他的类似:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;

/**
*
* @ORM\Entity
* @ORM\Table(name="user")
* @ORM\Entity(repositoryClass="AppBundle\Entity\UserRepository")
*/
class User implements UserInterface
最后是config.yml:

fos_oauth_server:
    db_driver: orm
    client_class: AppBundle\Entity\OAuthClient
    access_token_class: AppBundle\Entity\OAuthAccessToken
    refresh_token_class: AppBundle\Entity\OAuthRefreshToken
    auth_code_class: AppBundle\Entity\OAuthAuthCode
    service:
        options:
            access_token_lifetime: 3600

        user_provider: user_db
        #user_provider: AppBundle\Entity\UserRepository
        #user_provider: AppBundle\Entity\User
fos_oauth_server:
    db_driver: orm
    client_class: AppBundle\Entity\OAuthClient
    access_token_class: AppBundle\Entity\OAuthAccessToken
    refresh_token_class: AppBundle\Entity\OAuthRefreshToken
    auth_code_class: AppBundle\Entity\OAuthAuthCode
    service:
        options:
            access_token_lifetime: 3600
        user_provider: user.provider
现在它抛出一个异常:

[1] Symfony\Component\Debug\Exception\FatalThrowableError: Call to a member function loadUserByUsername() on null
    at n/a
        in /home/wanderson/api/vendor/friendsofsymfony/oauth-server-bundle/Storage/OAuthStorage.php line 161

    at FOS\OAuthServerBundle\Storage\OAuthStorage->checkUserCredentials(object(OAuthClient), 'admin', 'admin')
        in /home/wanderson/api/vendor/friendsofsymfony/oauth2-php/lib/OAuth2.php line 929

    at OAuth2\OAuth2->grantAccessTokenUserCredentials(object(OAuthClient), array('grant_type' => 'password', 'scope' => null, 'code' => null, 'redirect_uri' => null, 'username' => 'admin', 'password' => 'admin', 'refresh_token' => null))
        in /home/wanderson/api/vendor/friendsofsymfony/oauth2-php/lib/OAuth2.php line 815

    at OAuth2\OAuth2->grantAccessToken(object(Request))
        in /home/wanderson/api/vendor/friendsofsymfony/oauth-server-bundle/Controller/TokenController.php line 42

    at FOS\OAuthServerBundle\Controller\TokenController->tokenAction(object(Request))
        in  line 

    at call_user_func_array(array(object(TokenController), 'tokenAction'), array(object(Request)))
        in /home/wanderson/api/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php line 153

    at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), '1')
        in /home/wanderson/api/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php line 68

    at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), '1', true)
        in /home/wanderson/api/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php line 169

    at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
        in /home/wanderson/api/web/app_dev.php line 30

    at require('/home/wanderson/api/web/app_dev.php')
        in /home/wanderson/api/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/router_dev.php line 40

创建一个用户提供程序,或者如果您想为其使用存储库类,请阅读“如何定义类似存储库的服务”(我不知道它是否处于最新版本):

但我不建议这样做

<?php 

namespace AppBundle\Security\Provider\UserProvider;

use Doctrine\Common\Persistence\ObjectRepository;
use Doctrine\ORM\NoResultException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Serializer\Exception\UnsupportedException;
use Doctrine\ORM\EntityManager;

class UserProvider implements UserProviderInterface
{
    protected $class;

    protected $userRepository;

    public function __construct(EntityManager $entityManager, $class)
    {
        $this->class = $class;
        $this->userRepository = $entityManager->getRepository($class);
    }

    public function loadUserByUsername($username)
    {
        $user = $this->userRepository->findOneBy(array('username' => $username));
        if (null === $user) {
            $message = sprintf(
                'Unable to find an active User object identified by "%s"',
                $username
            );
            throw new UsernameNotFoundException($message, 0, $failed);
        }
        return $user;
    }

    public function refreshUser(UserInterface $user)
    {
        $class = get_class($user);
        if (false == $this->supportsClass($class)) {
            throw new UnsupportedException(
                sprintf(
                    'Instances of "%s" are not supported',
                    $class
                )
            );
        }
        return $this->userRepository->find($user->getId());
    }

    public function supportsClass($class)
    {
        return $this->class === $class
            || is_subclass_of($class, $this->class);

    }
}
在config.yml处更改fosoauth配置:

fos_oauth_server:
    db_driver: orm
    client_class: AppBundle\Entity\OAuthClient
    access_token_class: AppBundle\Entity\OAuthAccessToken
    refresh_token_class: AppBundle\Entity\OAuthRefreshToken
    auth_code_class: AppBundle\Entity\OAuthAuthCode
    service:
        options:
            access_token_lifetime: 3600

        user_provider: user_db
        #user_provider: AppBundle\Entity\UserRepository
        #user_provider: AppBundle\Entity\User
fos_oauth_server:
    db_driver: orm
    client_class: AppBundle\Entity\OAuthClient
    access_token_class: AppBundle\Entity\OAuthAccessToken
    refresh_token_class: AppBundle\Entity\OAuthRefreshToken
    auth_code_class: AppBundle\Entity\OAuthAuthCode
    service:
        options:
            access_token_lifetime: 3600
        user_provider: user.provider

关于security.yml您可以阅读:

创建一个用户提供程序,或者如果您想使用您的存储库类,请阅读“如何定义类似存储库的服务”(我不知道它是否处于最新版本):

但我不建议这样做

<?php 

namespace AppBundle\Security\Provider\UserProvider;

use Doctrine\Common\Persistence\ObjectRepository;
use Doctrine\ORM\NoResultException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Serializer\Exception\UnsupportedException;
use Doctrine\ORM\EntityManager;

class UserProvider implements UserProviderInterface
{
    protected $class;

    protected $userRepository;

    public function __construct(EntityManager $entityManager, $class)
    {
        $this->class = $class;
        $this->userRepository = $entityManager->getRepository($class);
    }

    public function loadUserByUsername($username)
    {
        $user = $this->userRepository->findOneBy(array('username' => $username));
        if (null === $user) {
            $message = sprintf(
                'Unable to find an active User object identified by "%s"',
                $username
            );
            throw new UsernameNotFoundException($message, 0, $failed);
        }
        return $user;
    }

    public function refreshUser(UserInterface $user)
    {
        $class = get_class($user);
        if (false == $this->supportsClass($class)) {
            throw new UnsupportedException(
                sprintf(
                    'Instances of "%s" are not supported',
                    $class
                )
            );
        }
        return $this->userRepository->find($user->getId());
    }

    public function supportsClass($class)
    {
        return $this->class === $class
            || is_subclass_of($class, $this->class);

    }
}
在config.yml处更改fosoauth配置:

fos_oauth_server:
    db_driver: orm
    client_class: AppBundle\Entity\OAuthClient
    access_token_class: AppBundle\Entity\OAuthAccessToken
    refresh_token_class: AppBundle\Entity\OAuthRefreshToken
    auth_code_class: AppBundle\Entity\OAuthAuthCode
    service:
        options:
            access_token_lifetime: 3600

        user_provider: user_db
        #user_provider: AppBundle\Entity\UserRepository
        #user_provider: AppBundle\Entity\User
fos_oauth_server:
    db_driver: orm
    client_class: AppBundle\Entity\OAuthClient
    access_token_class: AppBundle\Entity\OAuthAccessToken
    refresh_token_class: AppBundle\Entity\OAuthRefreshToken
    auth_code_class: AppBundle\Entity\OAuthAuthCode
    service:
        options:
            access_token_lifetime: 3600
        user_provider: user.provider

关于security.yml您可以阅读:

对不起,我是Symfony的新手,我不确定将此提供商服务配置放置在何处。我试图将它放在security.providers(security.yml)下,就像您的示例一样,我让Symfony告诉我该文件不包含有效的YAML。PS:除了构造函数之外,
UserProvider
类与我的
UserRepository
类几乎完全相同。对不起,我是Symfony的新手,我不知道该提供程序服务配置放在哪里。我试图将它放在security.providers(security.yml)下,就像您的示例一样,我让Symfony告诉我该文件不包含有效的YAML。注:
UserProvider
类除了构造函数外,与我的
UserRepository
类几乎相同。