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