-
Notifications
You must be signed in to change notification settings - Fork 453
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scopes and security #402
Comments
OAuth2 is about delegation, not authentication. When a client uses the resource owner password credentials grant, it just means that the resource owner allow it to access on its resources. The confusion is not in the use of scopes or grant types, but in the fact that this bundle is used to authenticate user while It should be use to protect a resource server. Regarding the resource owner password credentials grant, you should also keep in mind that it is suitable in cases where the resource owner has a trust relationship with the client (see RFC6749 section 4.3). |
Thank you for your quick response. Yes, the resources owner has a trust relationship with the client. But how can I restrict certains scopes to some client with this bundle actually ? I didn't clearly understood this sentence " but in the fact that this bundle is used to authenticate user while It should be use to protect a resource server". Do you mean I use this bundle I a uncorrect way ? Thanks. |
I am sorry but this feature is not yet implemented (see that -closed- PR). And I am not sure it will be implemented within the next weeks.
As you noted, the problem with the resource owner password credentials grant is that the client can issue access tokens at any time with any scopes. That is why you should avoid its use unless you have absolute confidence in it (which is the case as I understand). For me the main confusion comes from the fact that this bundle is often used to authenticate users, but OAuth2 is not designed for that purpose. |
Thanks. So the only solution to deal with scopes with this bundle now is to create users with wanted roles and then use password grant type ? Thank you again for your advices. |
Ran into the same problem, we are going to use client_credential grant. According to the doc (https://tools.ietf.org/html/rfc6749#section-3.3) :
What beats me is that OAuth2\Oauth2::createAccessToken() does not care what I save to database. |
@samusenkoiv I guess my comment is late but I also encountered with the need to change the Oauth2\OAuth2 class methods. parameters:
fos_oauth_server.server.class: My\Bundle\OAuth2\OAuth2 |
@pronata this is how I made it work =) anyway, thanks for trying to help. |
What is the status of updating the scope policy? Let it set scopes for concrete client and set default scope? |
I just wanted to share my (alternative/cleaner?) solution to overwrite the
<?php
namespace AppBundle\DependencyInjection\Compiler;
use AppBundle\AppBundle;
use AppBundle\Services\OAuth2;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class OverrideOAuthServiceCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$definition = $container->getDefinition('fos_oauth_server.server');
$definition->setClass(OAuth2::class);
}
}
class OAuth2 extends OAuth2Base
{
/**
* @inheritdoc
*/
public function createAccessToken(IOAuth2Client $client, $data, $scope = null, $access_token_lifetime = null,
$issue_refresh_token = true, $refresh_token_lifetime = null)
{
if ($client instanceof Client) {
$scope = implode(' ', $client->getAllowedScopes());
}
return parent::createAccessToken($client, $data, $scope, $access_token_lifetime, $issue_refresh_token, $refresh_token_lifetime);
}
} |
Thank you for your solution @chmielot. For anyone looking to reproduce this behaviour here is what I added to the previous code (use of OAuth2Base + string in $scope annotation in order to remove idea inspection)
And to my bundle file:
|
As an alternative / addition to the Client level scope restriction above - which can be useful on its own - I believe it could also be useful that the actual roles granted to the User (i.e. corresponding to the user credentials used for authentication) are enforced. This can be done by overloading the <?php
namespace AppBundle\Service;
use AppBundle\Entity\User;
use FOS\OAuthServerBundle\Storage\OAuthStorage as OAuthStorageBase;
use OAuth2\Model\IOAuth2Client;
class OAuthStorage extends OAuthStorageBase
{
public function checkUserCredentials(IOAuth2Client $client, $username, $password) {
$stored = parent::checkUserCredentials($client, $username, $password);
if ($stored == false) return $stored;
// Otherwise $stored['data'] is the User entity
/** @var User $user */
$user = $stored["data"];
// Get the roles of the user, convert it to the expected format for scopes
$roles = strtolower(implode(" ", str_replace("ROLE_", "", $user->getRoles())));
// Inject the scopes as default requirements for the $user
// N.B.: if the parent has already set a scope, we do not override it
$stored += array('scope' => $roles);
return $stored;
}
} ... and again creating a compiler pass (or modifying the previous one if you are doing the Client-level role restriction): <?php
namespace AppBundle\DependencyInjection\Compiler;
use AppBundle\Service\OAuthStorage;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class OverrideOAuthServiceCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$definition = $container->getDefinition('fos_oauth_server.storage.default');
$definition->setClass(OAuthStorage::class);
}
} Note that this will error rather than silently change the scope if a user requests a scope he is not entitled to. Hope that helps! |
@bpotard your solution is a life saver. You should write an article about it as the package is still lacking a native solution. Thank you. |
Hello everyone.
One concept of this bundle is a bit confusing me. When dealing with scope, why can we get any scope without permissions given by the client ?
I mean, any user can log ( with grant_type password ) and request any scope they want.
I'm facing this problem because of my current situation :
I one hand I have multiple users that log with grant_type password with the client. In the other hand I must configure a external trusted server access to certain restricted API routes that the lambda users should not be able to request. So I wanted to give a special role to my external server with scopes. Then the problem is that any user can get any scope they want.
How to deal with that ?
Thank you.
The text was updated successfully, but these errors were encountered: