自定义WebserviceUserProvider和FOSAuthServerBundle

时间:2017-01-05 12:59:59

标签: mongodb symfony oauth fosuserbundle fosoauthserverbundle

我使用基于本教程https://gist.github.com/tjamps/11d617a4b318d65ca583的SF2.8 API,除了我使用MongoDB。

当一个FOSUser(在带有oAuth表的数据库A上创建)连接到我的API时,我没有所需的所有信息,因为还有一个其他数据库。

我找到了一个SF文档,它解释了如何通过用自定义用户提供程序替换默认的FOS用户提供程序来自定义symfony默认身份验证。

所以我决定在这个doc上创建相同的架构:http://symfony.com/doc/2.8/security/custom_provider.html

在通过HTTP Post请求在/ oauth / v2 / token中询问我的oAuth令牌之前,我的overrided loadUserByUsername方法调用外部API并实现包含用户公司集合的WebserviceUser,以及具有用户名等基本字段,密码,盐等需要连接。

在loadUserByUsername调用之后,oAuth尝试将生成的accesstoken刷新到连接的用户进入DB,但抛出异常,因为要在AccessToken文档中保留的User文档是AppBundle \ Security \ User \ WebserviceUser而不是AppBundle \ Document \用户(FOSUser文档的子项)因此映射在持久化时失败。

我明白了:

  

班级' AppBundle \ Security \ User \ WebserviceUser'在链配置的命名空间中找不到AppBundle \ Document,FOS \ UserBundle \ Document,FOS \ OAuthServerBundle \ Document(500内部服务器错误)

我做错了吗?

编辑:我的新loadUserByUsername方法:

public function loadUserByUsername($username)
{
    $apiUser = $this->manager->getRepository('AppBundle:User')->findOneByUsername($username);

    if (is_null($apiUser)) {
        throw new UsernameNotFoundException(
            sprintf('Username "%s" does not exist.', $username)
        );
    }

    $userData = $this->client->httpGetList("user", ['filter_usrMail' => $apiUser->getEmail()]);
    $userData = $userData[array_keys($userData)[0]];

    $companies = isset($userData['usrCompany']) ? $userData['usrCompany'] : [];

    if ($userData) {
        $role = isset($userData['usrRole']) ? [$userData['usrRole']] : ['ROLE_USER'];

        $user = new WebserviceUser($apiUser->getUsername(), $apiUser->getPassword(), $apiUser->getSalt(), $apiUser->getRoles());
        $user->setCompanies($companies);
        $user->setApiUsername($apiUser->getUsername());

        return $user;
    }

    throw new UsernameNotFoundException(
        sprintf('Username "%s" does not exist.', $username)
    );
}

fos_oauth_server yml conf:

db_driver:           mongodb
client_class:        AppBundle\Document\Client
access_token_class:  AppBundle\Document\AccessToken
refresh_token_class: AppBundle\Document\RefreshToken
auth_code_class:     AppBundle\Document\AuthCode
service:
    user_provider: app.webservice_user_provider

services.yml conf:

app.webservice_user_provider:
    class: AppBundle\Security\User\WebserviceUserProvider
    arguments: ['@my_communicator.client', '@session', '@doctrine.odm.mongodb.document_manager', '%session_refresh_ttl%']

security.yml conf:

  encoders:
        AppBundle\Security\User\WebserviceUser: bcrypt
        FOS\UserBundle\Model\UserInterface: bcrypt
    providers:
        webservice:
            id: app.webservice_user_provider
        #in_memory:
        #    memory: ~

        fos_userbundle:
            id: fos_user.user_provider.username

    role_hierarchy:
        ROLE_ADMIN: ROLE_USER

    firewalls:
        oauth_token:                                   # Everyone can access the access token URL.
            pattern: ^/oauth/v2/token
            security: false

        api:
            pattern: ^\/api(?!\/doc|\/v[0-9][\.0-9]*\/core(\/createaccount|\/clients)) # All URLs are protected (except api doc and api create account)
            fos_oauth: true                            # OAuth2 protected resource
            stateless: true                            # Do no set session cookies
            anonymous: false                           # Anonymous access is not allowed
            access_denied_handler: app.listener.access_denied.handler

        apidoc:
            pattern: ^\/api\/doc
            anonymous: false
            security: false

    access_control:
        - { path: ^\/api\/v[0-9][\.0-9]*\/(?!(admin|core)), roles: ROLE_USER }
        - { path: ^\/api\/v[0-9][\.0-9]*\/(admin|core)(?!(\/createaccount|\/clients)), roles: ROLE_ADMIN }
        - { path: ^\/api\/v[0-9][\.0-9]*\/core(\/createaccount|\/clients), roles: IS_AUTHENTICATED_ANONYMOUSLY, ips: [127.0.0.1, localhost, ::1] }
        - { path: ^\/api\/v[0-9][\.0-9]*\/core(\/createaccount|\/clients), roles: ROLE_NO_ACCESS }

    access_decision_manager:
        strategy: unanimous

0 个答案:

没有答案