FriendsOfSymfony / FOSOAuthServerBundle

A server side OAuth2 Bundle for Symfony
1.09k stars 451 forks source link

OAuthToken with null user is not authenticated anymore since symfony 5.4 #688

Open 4rthem opened 2 years ago

4rthem commented 2 years ago

I'm using ->isGranted('ROLE_SCOPE1') to authorize a machine token so there is no user context.

Since Symfony 5.4, AuthorizationChecker relies on getUser() instead of getToken() which make user-less access tokens not authenticated (cf diff). In some way Symfony introduced a BC break but I think the OAuthToken should fill the user property with a string constant to pass this condition.

What do you think?

@nicolas-grekas what would be the good practice?

LeoAdamek commented 2 years ago

I'm also having this issue, specifically when using a client_credentials grant. Is there a workaround for this, perhaps setting the user to the oauth application itself?

vladimir-light commented 2 years ago

@4rthem , @LeoAdamek

In some way Symfony introduced a BC break

I agree, it's very odd, especially for client_credentials grant where technically no user exists.

My quick and dirty solution was to override vendor/friendsofsymfony/oauth-server-bundle/Security/Authentication/Provider/OAuthProvider.php with my own. Actually, I only needed to adjust the authenticate() method, so I could create a "dummy-user" (something which implements UserInterface) on-the-fly and set it to $token

For Example:

src/Security/OAuth/Provider/OAuthProvider.php with fully-qualified namespace of App\Security\OAuth\Provider\OAuthProvider

and then configure it as a "replacement" for fos_oauth_server.security.authentication.provider service.

in your config/services.yaml add the following:

fos_oauth_server.security.authentication.provider:
        class: App\Security\OAuth\Provider\OAuthProvider
        arguments: [ ~, '@fos_oauth_server.server', ~ ]
        public: false

I tried to decorate the original fos_oauth_server.security.authentication.provider service but didn't get it working, so I just copied everything.

In authenticate() method right after verifyAccessToken($tokenString) you can check for $user === null and create one on-the-fly. I decided to create a ClientCredentialsDummyUser model which implements \Symfony\Component\Security\Core\User\UserInterface for that special case.

LeoAdamek commented 2 years ago

While its definitely not an ideal solution, and it lacks some things I'd like to do with it, it does at least get around the issue.

INHack20 commented 2 years ago

+1

aanair08 commented 1 year ago

+1