![](/img/trans.png)
[英]How to override TokenController for FOSOAuthServerBundle?
[英]How to deal with ROLES and FOSOAuthServerBundle scopes
我有一个基本的api,使用FOSOAuthServerBundle验证用户。 用户可以拥有ROLE_USER和ROLE_ADMIN角色。 基于FOSOAuthServerBundle文档,默认行为是使用范围作为角色,所以我认为当我有一个普通用户时,bundle会在响应中返回scope: user
,当它是admin用户时,将返回scope: admin
但它不是这样的。 捆绑包返回supported_scopes
条目中配置的任何内容。 下面是我的config.yml
。
fos_oauth_server:
service:
options:
supported_scopes: user admin
security.yml
access_control
部分为空,我的firewalls
部分如下:
firewalls:
users_create:
pattern: ^/v1/users
methods: [POST]
security: false
api:
pattern: ^/
security: true
fos_oauth: true
stateless: true
access_control:
# You can omit this if /api can be accessed both authenticated and anonymously
这样,即使用户没有ROLE_ADMIN角色,bundle也始终将user admin
作为范围返回。
{
"access_token": "ZGQ2ODE5ZjAzNTZkOWY0OWMyNmZmODE4MjcwZTJmYjExNzY0NzQxOTRmMzk4NzA2Mjc2NjIyZmY1ZDgwMzk4NA"
"expires_in": 3600
"token_type": "bearer"
"scope": "user admin"
"refresh_token": "NmM5ZGFmNzBiNTNjYmQzMTQ1MTk0ODJjOTAxMWU0YWIwMzM1MzgyODg4ZTAzNTI5ZTk2MDc3OGU2MTg0MWZiMA"
}
我错过了什么? 用户角色是否附加到令牌范围? 有没有更好的方法来了解我的用户是否是管理员?
在doc中 ,默认行为是使用角色映射范围。 在您的情况下,角色将是ROLE_USER和ROLE_ADMIN。
现在要限制使用,你可以像这样编辑你的security.yml文件:
# app/config/security.yml
security:
access_control:
- { path: ^/api/super/secured, role: ROLE_ADMIN }
- { path: ^/api/general, role: ROLE_USER }
要限制在控制器内的访问,您可以使用:
if ($this->get('security.context')->isGranted('ROLE_ADMIN')) {
// the user has the ROLE_ADMIN role, so act accordingly
}
再次来自doc ,
现在,客户端在请求访问令牌时将能够传递scope参数。
希望这可以帮助。
更新:
FOSOAuthServerBundle
基于令牌对您的用户进行身份验证,因此您不必担心范围,这与角色不同。 在你的控制器里面你可以得到$this->getUser()
来获得当前经过身份验证的用户。 如果这样做,那么检查isGranted
是否也isGranted
正常工作。
http://symfony.com/doc/current/book/security.html
public function helloAction($name)
{
// The second parameter is used to specify on what object the role is tested.
$this->denyAccessUnlessGranted('ROLE_ADMIN', null, 'Unable to access this page!');
// Old way :
// if (false === $this->get('security.authorization_checker')->isGranted('ROLE_ADMIN')) {
// throw $this->createAccessDeniedException('Unable to access this page!');
// }
// ...
}
如果$this->getUser()
不起作用,则必须在AccessToken
实体上设置fetch
到EAGER
。
class AccessToken extends BaseAccessToken
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Client")
* @ORM\JoinColumn(nullable=false)
*/
protected $client;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\User", fetch="EAGER")
*/
protected $user;
}
github上存在一个问题,可追溯到2013年 。 如果您阅读该问题并按照链接进行操作,最终将会向用户Spomky创建自己的库和Symfony包 ,并被建议作为 FOSAuthServerBundle的维护者。 一旦稳定,FOS组织似乎将Spomky的工作合并到FOSOAuthServerBundle的下一个主要版本中。
您可以返回用户帐户信息以及令牌。
这是我处理类似情况的方法,我创建了一个代理路由,将用户名和密码作为请求参数,将oauth客户端信息添加到请求中,并将请求转发给Oauth Token Action。 然后我获取该信息并返回用户信息以及令牌。
/**
* @REST\Post("/authorize")
*/
public function loginAction(Request $request){
$request->request->add( array(
'grant_type' => 'password',
'client_id' => $this->container->getParameter('oauth_client_id') . "_" . $this->container->getParameter('oauth_client_random_id'),
'client_secret' => $this->container->getParameter('oauth_client_secret')
));
$tokenAction = $this->get('fos_oauth_server.controller.token')->tokenAction($request);
$tokenObject = json_decode( $tokenAction->getContent() );
if(key_exists('error_description', $tokenObject)){
return $this->view(["error" => $tokenObject->error_description], 401);
};
$user = $this->getDoctrine()->getRepository('\App\Entity\Oauth\AccessToken')->findOneBy( array('token' => $tokenObject->access_token ) )->getUser();
$return = array(
"roles" => $user->getUser()->getRoles(),
"access_token" => $tokenObject->access_token,
"expires_in" => $tokenObject->expires_in,
"token_type" => $tokenObject->token_type,
"scope" =>$tokenObject->scope,
"refresh_token" => $tokenObject->refresh_token
);
return $this->view($return);
}
我使用此路由进行身份验证/令牌生成,而不是使用OAuthBundle附带的路由
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.