Symfony FOSOAuthServerBundle: access token not detected - symfony

I'm using FOSOAuthServerBundle as my oauth endpoint. I succesfully generated a token using the Resource Owner Password Credentials grant method:
{
"access_token": "MY-FOO-TOKEN",
"expires_in": ​3600,
"token_type": "bearer",
"scope": "read",
"refresh_token": "MY-BAR-REFRESH-TOKEN"
}
Now I would like to use it to get some protected resources. So I did:
curl -X GET -H "Authorization: Bearer MY-FOO-TOKEN" "http://localhost:8000/api/a-bar-resource"
The Bearer do not seem to be detected.
INFOS:
echo $this->get('security.token_storage')->getToken(); gives:
AnonymousToken(user="anon.", authenticated=true, roles="")
In the headers there is:
["authorization"]=> /** <-- Is the lowercase OK? **/
array(1) {
[0]=>
string(93) "Bearer MY-FOO-TOKEN"
}
I also tried to pass access_token as a query parameter, without success.
Now I'm guessing something is wrong with the config.yml or the security.yml. Here are some selected parts:
config.yml:
fos_oauth_server:
[...]
service:
options:
supported_scopes: read
user_provider: fos_user.user_provider.username_email
security.yml:
security:
[...]
firewalls:
api:
pattern: ^/api
fos_oauth: true
stateless: true
anonymous: false
access_control:
- { path: ^/api, roles: [ IS_AUTHENTICATED_ANONYMOUSLY ] }

I finally found what was causing the problem. I had a firewall that was nullifying the other firewall, because of same patterns:
security:
[...]
firewalls:
other_firewall: #this one
pattern: ^/
anonymous: true
api:
pattern: ^/api
fos_oauth: true
stateless: true
anonymous: true
I also think that an authentication made in one firewall is not available in an other firewall, so diminishing the number of firewalls to the strict minimum (one not secured, one with auth etc.) is a good practice. Then using access_control for fine access.

Related

Symfony 6 - lexik JWT - Authenticator does not support the request

I'm having some problems with lexik JWT bundle and Symfony 6.0, for swagger I use NelmioApiDocBundle.
The thing is, that every in swagger works before I decide to apply my Authorization Token (Bearer token), which is generated from lexik JWT. But once I get my token generated through /api/sign/in endpoint, and put it into the field, suddenly all endpoints stop working. Like the swagger has this loading animation, but no request comes (tested with xDebug, but also symfony profiler).
Funny thing is when I use Postman and apply the token there, I immediately get a correct response. So I'm not sure where or what's the problem, but when calling from Swagger, I can see docker debug messages saying: PHP message: [debug] Authenticator does not support the request.
I will put my configuration below. Thanks in advance.
lexik_jwt_authentication.yaml:
lexik_jwt_authentication:
secret_key: '%env(resolve:JWT_SECRET_KEY)%'
public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
pass_phrase: '%env(JWT_PASSPHRASE)%'
token_ttl: 8640000
user_id_claim: id
user_identity_field: email
security.yaml
security:
enable_authenticator_manager: true
password_hashers:
App\Entity\User:
algorithm: bcrypt
cost: 10
providers:
app_user_provider:
entity:
class: App\Entity\User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/api/sign
stateless: true
provider: app_user_provider
json_login:
check_path: /api/sign/in
username_path: email
password_path: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
provider: app_user_provider
pattern: ^/api
stateless: true
jwt: ~
access_control:
- { path: ^/api/sign/, roles: PUBLIC_ACCESS }
- { path: ^/api/(doc|doc.json), roles: PUBLIC_ACCESS }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
nelmio_api_doc.yaml
nelmio_api_doc:
documentation:
servers:
- url: http://bp.project
info:
title: BP PROJECT
description: This is an awesome app!
version: 1.0.0
components:
securitySchemes:
Bearer:
type: http
scheme: bearer
bearerFormat: JWT
security:
Bearer: [ ]
areas: # to filter documented areas
path_patterns: # an array of regexps
- ^/api(?!/(doc|doc.json|docs.{_format}|{index}.{_format}|contexts/{shortName}.{_format})$) # Accepts routes under /api except ...
models: { use_jms: false }
Found out api_platform swagger and nelmio are both interacting somehow, since I added this into api_platform.yaml and the header was available in nelmio too, which now works.
swagger:
versions: [3]
api_keys:
apiKey:
name: Authorization
type: header

I can't get the user from JWT

I have a project with Symfony 5.1 using Lexik JWT v2.8.0, gesdinet jwt refresh token v0.9.1 and my own entity user. I can log in with JWT and get the token, save it in a HttpOnly cookie and use it with the protected APIs successfully.
My web app has some API Rest but it has also pages to browse. So my intention is do it all from API, but also login in the web browser when user obtains a token.
But as api login is stateless, after the success login the web profiler still shows logged in as anon. and I can't get te user from the token. I made a service to get the user from the token, to call it in the controller and send some logged in user data to the front end.
I've got a service from this question. The service I have implemented to get the user is:
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use UserBundle\Domain\Entity\User;
class UserService
{
private TokenStorageInterface $tokenStorage;
private JWTTokenManagerInterface $jwtManager;
public function __construct( TokenStorageInterface $storage, JWTTokenManagerInterface $jwtManager )
{
$this->tokenStorage = $storage;
$this->jwtManager = $jwtManager;
}
public function getCurrentUser() : ?User
{
$decodedJwtToken = $this->jwtManager->decode($this->tokenStorage->getToken());
if ($decodedJwtToken instanceof TokenInterface) {
$user = $decodedJwtToken->getUser();
return $user;
} else {
return null;
}
}
}
And it is declared as a service:
get.token.user.service:
class: UserBundle\Domain\Service\UserService
arguments: [ '#security.token_storage' ]
But all I get from $this->tokenStorage->getToken() is a web token with "anon." user, so it is not a JWT and jwtManager can't decode it.
UserService.php on line 25:
Symfony\Component\Security\Core\Authentication\Token\AnonymousToken {#16 ▼
-secret: "RXVaVx3"
-user: "anon."
-roleNames: []
-authenticated: true
-attributes: []
}
I also tried to get the jwt from the cookie in the controller and send it to the service as an argument, but I get an error from decode that I'm passing a string and it expects a TokenInterface object, so it did not worked neither.
How can I get the user from the token in the service? is there a best practice to login in the web through api than get the user from the jwt and send it to the render?
Edit: add the code to use lexik jwt and to save token in cookie:
# /config/packages/lexik_jwt_authentication.yaml
lexik_jwt_authentication:
secret_key: '%env(resolve:JWT_SECRET_KEY)%'
public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
pass_phrase: '%env(JWT_PASSPHRASE)%'
token_ttl: 3600
user_identity_field: email
token_extractors:
cookie:
enabled: true
name: BEARER
the security file code
# /config/packages/security.yaml
security:
encoders:
UserBundle\Domain\Entity\User:
algorithm: auto
providers:
app_user_provider:
entity:
class: UserBundle\Domain\Entity\User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/api/login
stateless: true
anonymous: true
json_login:
provider: app_user_provider
check_path: /api/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
refresh:
pattern: ^/api/token/refresh
stateless: true
anonymous: true
register:
pattern: ^/api/register
stateless: true
anonymous: true
api:
pattern: ^/api
stateless: true
anonymous: true
provider: app_user_provider
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
main:
anonymous: true
lazy: true
provider: app_user_provider
access_control:
- { path: ^/api/user, roles: IS_AUTHENTICATED_ANONYMOUSLY, methods: [GET] }
- { path: ^/api/linkpage, roles: IS_AUTHENTICATED_ANONYMOUSLY, methods: [GET] }
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/token/refresh, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
Listener to save jwt in a cookie and avoid the token to be in the response:
use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent;
use Symfony\Component\HttpFoundation\Cookie;
class AuthenticationSuccessListener
{
private bool $secure = false;
private int $tokenTtl;
public function __construct(int $tokenTtl)
{
$this->tokenTtl = $tokenTtl;
}
public function onAuthenticationSuccess( AuthenticationSuccessEvent $event)
{
$response = $event->getResponse();
$data = $event->getData();
$token = $data['token'];
unset($data['token']); // remove token from response. It works.
unset($data['refresh_token']); // remove token from refresh token, even though I still get this token in the response
$event->setData($data);
$response->headers->setCookie(
new Cookie(
'BEARER',
$token,
(new \DateTime())->add(new \DateInterval('PT'. $this->tokenTtl . 'S')),
'/',
null,
$this->secure
)
);
}
}
#services.yaml
app.listener.authenticationsuccesslistener:
class: UserBundle\Application\Listeners\AuthenticationSuccessListener
arguments: ['%lexik_jwt_authentication.token_ttl%']
tags:
- { name: kernel.event_listener, event: lexik_jwt_authentication.on_authentication_success, method: onAuthenticationSuccess }
I still coded 2 more listeners for the refresh token, but I don't think they are needed.
The rest of the authentication is the default authentication code from lexik jwt bundle.
In the BEARER cookie is stored the jwt with the correct format, something like this:
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1OTgzNTE0ODYsImV4cCI6MTU5ODM1NTA4Niwicm9sZXMiOlsiUk9MRV9BRE1JTiIsIlJPTEVfVVNFUiJdLCJlbWFpbCI6ImFkbWluQGVtYWlsLmNvbSJ9.p5WYCxEE-VSxp09Eo7CxXoxi6zy1ZcnLJiBe1YGsrk3iFm7T-6JAWbvyb9ZW_-1jtpYcWQlFOjOf7uET4wRHvlvygnPOeZck7tZM8TUlSqMXIllMeVARz8mEUvXVwhDWEk5T7Ibw9c3VgfvyiLUgSb_cmSyK3DwtgPCd9vOYarkag9XKxkxNI9M1OHGL61v1NoQHdkXloC72xdUUMcj5Y8yCJWZFdOp8-Xtfq8ZChAHzwCjXUhC3VnBqZcMT0tAvtilwTGDYDykppNKK1vbNoyOex47wQH_ILEFuX5Eh1p2xfbc0lWm3Ip21z3EQ2M_eOQgZvHR65T3b2dv9g5GPiFp3CNo8AuW8m6rXjWK6NZXJO8qYodxI5cUYYyFooCfVXXU8JXzGQfCZIdOPw-iBGzQEfFuLL50_sAOVcxjklAYCFZYRHwFKWmwl1BwJF4mAw4jnNIAdMmc66Z17ul2Jep9apOO90C1dZzGuVKxWqglc9GZo7-teHt0dMsg0ADrvaOKNJUwDBGJ4lZpWx6_stcl7DkCdc5k1kePGdLa7YXRO3umPwa_FVYVgnT_Z9x7RtfnGioa2TZJCIdbJnuj0L90vkgFBjHqFdVydDaaBu3Y0mKoQ2v3Sf1so4-uwJm8z1vQVZleMQgFibMiyyk3YyDidhPSxxyp4u-4xPNOSDNo
If I am not logged in and don't have jwt or I delete the BEARER cookie I can't access the protected APIs ({"code": 401, "message": "JWT Token not found"}), when I have the jwt assigned I can request APIs correctly.
The problem was on the security.yaml configuration, specifically in the firewalls.main section, where I had to add the jwt_token_authenticator as the guard. Finally, my security.yaml is:
security:
encoders:
UserBundle\Domain\Entity\User:
algorithm: auto
providers:
app_user_provider:
entity:
class: UserBundle\Domain\Entity\User
property: email
jwt:
lexik_jwt: ~
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/api/login
stateless: true
anonymous: true
json_login:
provider: app_user_provider
check_path: /api/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
require_previous_session: false
refresh:
pattern: ^/api/token/refresh
stateless: true
anonymous: true
register:
pattern: ^/api/register
stateless: true
anonymous: true
api:
pattern: ^/api
stateless: true
anonymous: true
provider: jwt
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
main:
anonymous: true
lazy: true
provider: jwt
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
logout:
path: app_logout
target: /
access_control:
- { path: ^/api/login_check, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/token/refresh, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/logout, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
Then I had some problems with the logout, as the logout didn't erase the jwt cookies and the logout kept me logged in. So I made a Listener to the LogoutEvent and made the listener delete the cookies.
use Symfony\Component\Security\Http\Event\LogoutEvent;
class LogoutListener
{
public function onSymfonyComponentSecurityHttpEventLogoutEvent(LogoutEvent $event)
{
$response = $event->getResponse();
$response->headers->clearCookie('BEARER');
$response->headers->clearCookie('REFRESH_TOKEN');
$event->setResponse($response);
}
}
and declared it as a service:
app.listener.logout:
class: UserBundle\Application\Listeners\LogoutListener
tags:
- name: 'kernel.event_listener'
event: 'Symfony\Component\Security\Http\Event\LogoutEvent'
dispatcher: security.event_dispatcher.main
And now the login is working on the web without having to decode the jwt with the service I was using and pass the user to the front. Though the service that decoded the jwt, now is working fine.
I've lost almost a week with this issue, but finally I've found a solution and it's working fine. So I'll post it here to save time if anybody has some similar issue.

hslavich / OneloginSamlBundle problem on the acs route

I installed and configured the bundle as indicated in the readme file.
I success to be redirected to the azure login page. After that I input email and password, I'am redirected to the website.
But the process to be logged into my website seems broken.
I'am redirected to /saml/acs with an error.
Here is the log message:
request.INFO: Matched route "saml_acs". {"route":"saml_acs","route_parameters":{"_controller":"Hslavich\\OneloginSamlBundle\\Controller\\SamlController::assertionConsumerServiceAction","_route":"saml_acs"},"request_uri":"https://myapp.com/saml/acs","method":"POST"} []
[2020-06-11 11:50:57] security.ERROR: Found attributes: Array ( [sessionIndex] => _6789dbcf-b1a7-44b5-8e55-817affff1900 ) [] []
[2020-06-11 11:50:57] request.CRITICAL: Uncaught PHP Exception Exception: "Attribute 'uid' not found in SAML data" at /var/www/myapp/vendor/hslavich/oneloginsaml-bundle/Security/Firewall/SamlListener.php line 57 {"exception":"[object] (Exception(code: 0): Attribute 'uid' not found in SAML data at /var/www/myapp/vendor/hslavich/oneloginsaml-bundle/Security/Firewall/SamlListener.php:57)"} []
What do I miss ? Do I have to create my own acs action ?
Here is my configuration
config file:
idp:
entityId: 'https://sts.windows.net/xxxXXXxxxXXX/'
singleSignOnService:
url: 'https://login.microsoftonline.com/xxxXXXxxxXXX/saml2'
binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
singleLogoutService:
url: 'https://login.microsoftonline.com/xxxXXXxxxXXX/saml2'
binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
x509cert: 'xxxXXXxxxXXXxxxXXXxxxXXXxxxXXXxxxXXXxxxXXXxxxXXX'
sp:
entityId: 'https://myapp.com/saml/metadata'
assertionConsumerService:
url: 'https://myapp.com/saml/acs'
binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'
singleLogoutService:
url: 'https://myapp.com/saml/logout'
binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
privateKey: '-----BEGIN PRIVATE KEY-----
xxxXXXxxxXXXxxxXXXxxxXXXxxxXXXxxxXXX
-----END PRIVATE KEY-----'
# Optional settings
baseurl:
strict: true
debug: true
security:
nameIdEncrypted: false
authnRequestsSigned: false
logoutRequestSigned: false
logoutResponseSigned: false
wantMessagesSigned: false
wantAssertionsSigned: false
wantNameIdEncrypted: false
requestedAuthnContext: true
signMetadata: false
wantXMLValidation: true
signatureAlgorithm: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'
digestAlgorithm: 'http://www.w3.org/2001/04/xmlenc#sha256'
contactPerson:
technical:
givenName: 'Tech User'
emailAddress: 'techuser#example.com'
support:
givenName: 'Support User'
emailAddress: 'supportuser#example.com'
And my security file:
firewalls:
app:
pattern: ^/
anonymous: true
saml:
# Match SAML attribute 'uid' with username.
# Uses getNameId() method by default.
username_attribute: uid
# Use the attribute's friendlyName instead of the name
use_attribute_friendly_name: true
check_path: /saml/acs
login_path: /saml/login
logout:
path: /saml/logout
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
form_login:
login_path: login
check_path: login
default_target_path: homepage
always_use_default_target_path: true
logout:
path: logout
target: login
access_control:
- { path: ^/saml/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/saml/metadata, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: ROLE_USER }
- { path: ^/admin, roles: ROLE_ADMIN }
access_denied_url: login
I miss something I guess. Thank you by advance for your help.
In my case, the following option was causing attributes from the SAML assertion not to be parsed correctly, resulting in exactly the same outcome as you're seeing (sessionIndex being the only recognized "attribute"):
use_attribute_friendly_name: true
I needed to change it to:
use_attribute_friendly_name: false
Then the attributes array got populated correctly.
PS: Additionally, in my case, I had to change the username_attribute from uid to email too, since there was no uid attribute in "my" SAML assertion.

Lexik JWT returns 401 Unauthorized

I am using LexikJWTBundle for a RESTful API.
Login works just fine and I get my token. But when I make a GET request I get a 401 with no content.
The Authorization header seems ok since I get this in the profiler:
Request Headers: authorization: Bearer {token}
Request Server Parameters: HTTP_AUTHORIZATION: Bearer {token}
The 401 I get is from: https://github.com/lexik/LexikJWTAuthenticationBundle/blob/master/Security/Firewall/JWTListener.php#L80
I've tried different solutions but still it's not working.
Would you have any idea on how to resolve/debug this?
My config:
# config.yml
...
lexik_jwt_authentication:
private_key_path: %kernel.root_dir%/var/jwt/private.pem # ssh private key path
public_key_path: %kernel.root_dir%/var/jwt/public.pem # ssh public key path
pass_phrase: 'TEST' # ssh key pass phrase
token_ttl: 86400 # token ttl - defaults to 86400
And
# security.yml
security:
role_hierarchy:
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_SONATA_ADMIN, ROLE_ALLOWED_TO_SWITCH]
# http://sonata-project.org/bundles/admin/2-3/doc/reference/security.html
# set access_strategy to unanimous, else you may have unexpected behaviors
access_decision_manager:
strategy: unanimous
encoders:
FOS\UserBundle\Model\UserInterface: sha512
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
api_login:
pattern: ^/api/login # Default: .*
provider: fos_userbundle
# form login
form_login:
login_path: fos_user_security_login
# csrf_provider: form.csrf_provider # Default: my.csrf_provider.id
# LexikJWT # 09/01/15 - Note: provient de la configuration officielle.
check_path: api_login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
require_previous_session: false
anonymous: true # Default: ~
api:
pattern: ^/api
stateless: true
lexik_jwt:
authorization_header: # check token in Authorization Header
enabled: true
prefix: Bearer
anonymous: true
access_control:
# Secured part of the site
# This config requires being logged for the whole site and having the admin role for the admin part.
# Change these rules to adapt them to your needs
- { path: "^/api/contacts$", roles: IS_AUTHENTICATED_ANONYMOUSLY, methods: [POST] }
- { path: "^/api/users/dt$", roles: IS_AUTHENTICATED_ANONYMOUSLY, methods: [GET] }
- { path: "^/api/users$", roles: IS_AUTHENTICATED_ANONYMOUSLY, methods: [POST] }
- { path: "^/api", roles: [IS_AUTHENTICATED_FULLY, ROLE_API] }
I just found a solution on the same problem
Here my security.yml
firewalls:
dev:
pattern: ^/(_(profiler|wdt|error)|css|images|js)/
security: false
login:
pattern: ^/api/login
stateless: true
anonymous: true
provider: user_db
form_login:
check_path: /api/login_check
username_parameter: _username
password_parameter: _password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
require_previous_session: false
api:
pattern: ^/api
stateless: true
lexik_jwt:
authorization_header: # check token in Authorization Header
enabled: true
prefix: Bearer
throw_exceptions: false # When an authentication failure occurs, return a 401 response immediately
create_entry_point: true # When no authentication details are provided, create a default entry point that returns a 401 response
authentication_provider: lexik_jwt_authentication.security.authentication.provider
My problem was the username and the password parameters. I change "username" by "_username" and "password" by "_password"
You should add the ROLE_API in the role_hierarchy of your security.yml :
role_hierarchy:
# ...
ROLE_API: [ROLE_USER]
Then, users ranked with ROLE_API can access routes restricted to IS_AUTHENTICATED_FULLY.
Also, if you are using a web server, try to use your application using the built-in server (i.e. app/console server:run).
Apache seems to modify the token in headers.
LexikJWTBundle generates token so user's credentials are valid.
Problem occurs when you try to access secured routes (behind "^/api" path).
You should definitely check roles assigned to user. Maybe ROLE_API is missing and user is not fully authenticated.

Limit access to routes with the FOSOAuthServerBundle

I have created a REST API, i'm actually trying to secure it with the FOSOAuthServerBundle.
I created the route newclient to generate new client, now i would like to allow only the 'admin' to access to this url.
I guess it's possible to do this with scopes but i can't figure out how.
Here is my security.yml:
security:
providers:
user_provider:
id: user_provider
firewalls:
doc:
pattern: ^/doc
security: false
oauth_token:
pattern: ^/oauth/v2/token
security: false
oauth_authorize:
pattern: ^/oauth/v2/auth
provider: user_provider
anonymous: true
api:
pattern: ^/
fos_oauth: true
stateless: true
anonymous: false
access_control:
- { path: ^/, roles: ROLE_CLIENT }
- { path: ^/newclient, roles: ROLE_ADMIN }
My config.yml
fos_oauth_server:
db_driver: orm
client_class: WS\RESTBundle\Entity\Client
access_token_class: WS\RESTBundle\Entity\AccessToken
refresh_token_class: WS\RESTBundle\Entity\RefreshToken
auth_code_class: WS\RESTBundle\Entity\AuthCode
Any tips ?
Actually desling with scopes is not the best way to do it, plus the bundle does not support it : https://github.com/FriendsOfSymfony/FOSOAuthServerBundle/issues/231
I made use the User model, add a "role" method and check if the current user's role is enough to access the to the routes.
Here is the piece of code
//Get the current user, check if it's an admin
$token = $this->container->get('security.context')->getToken()->getToken();
$accessToken = $this->container
->get('fos_oauth_server.access_token_manager.default')
->findTokenBy(array('token' => $token));
$client = $accessToken->getClient();
if ($client->getRole() == 'admin') {
...
}
Not sure if it's the best way to do it, any advices welcome !

Resources