1

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

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

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

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

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

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

我懂了 :

在链配置的命名空间 AppBundle\Document、FOS\UserBundle\Document、FOS\OAuthServerBundle\Document 中找不到类“AppBundle\Security\User\WebserviceUser”(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 配置:

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 配置:

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

security.yml 配置:

  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
4

0 回答 0