我正在使用基于本教程 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