Open ghost opened 4 months ago
Are you using client-credentials for authentication? I've had a similar issue due to changes that have been made in oauth2-server. Before oauth2-server version 9.0.0 the subject field in the JWT token was empty when using client credentials. This commit add a change that will fill the client id in the subject field. When the subject field is empty in the JWT this code will return a NullUser object and not call the user provider, but because this field is not empty anymore after version 9.0.0 the user provider is now being called and throws an error. I think the oauth2-server-bundle should provide a user provider for this or return the NullUser in some other way. The oauth2-server-bundle 0.9.0 upgrade broke our client-credentials flow without it being a mayor release :(
Also experiencing the issue with client credentials that @bartholdbos is describing. Our tests started failing when updating to 0.9.0 because the UserInterface::createFromPayload was called, and no payload was passed with the JWT array and only the Client ID as the UserName.
This breaking change was not documented in the Release notes and there is no documentation on what should be done to resolve this issue. Any help would be appreciated. For now will stay it at 0.8.0 until there is a resolution
It seems that previously NullUser
(League\Bundle\OAuth2ServerBundle\Security\User\NullUser
) was used, since $userIdentifier
($psr7Request->getAttribute('oauth_user_id', '')
from OAuth2Authenticator
) was empty string, - that's because 'sub'
claim of jwt token was never set (at the point BearerTokenValidator::validateAuthorization
it is empty string)
Hence, it looks like a fix for claim
attribute, but it's definitely necessary to have some user provider.
In my opinion, since we already have user identifier, it would be better if league library used some InMemoryUser
(or even dedicated Oauth2User
) containing that identifier
Same problem here, @bartholdbos perfectly explained it. I can't understand how the issue went unnoticed since the change is so breaking.
As for resolution:
Problem with own user provider is that all SF user providers has to implement Symfony\Component\Security\Core\User\UserProviderInterface
which in turn forces you to return class implementing Symfony\Component\Security\Core\User\UserInterface
in loadUserByIdentifier
method. IMHO the way to go is to make Client
class implement UserInterface
and then just use standard EntityUserProvider. For now I got it working by creating my own client class and setting it in config to be used in place of original Client
:
namespace App\Entity;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use League\Bundle\OAuth2ServerBundle\Model\AbstractClient;
use Symfony\Component\Security\Core\User\UserInterface;
#[ORM\Entity]
class Oauth2Client extends AbstractClient implements UserInterface
{
#[ORM\Id]
#[ORM\Column(type: Types::STRING, length: 32)]
protected string $identifier;
public function getRoles(): array
{
return [];
}
public function eraseCredentials()
{
}
public function getUserIdentifier(): string
{
return $this->identifier;
}
}
security:
providers:
...
oauth2_server_bundle:
entity:
class: App\Entity\Oauth2Client
property: identifier
league_oauth2_server:
client:
classname: App\Entity\Oauth2Client
And then use oauth2_server_bundle
provider in firewall that requires oauth2.
Would be nice if this was not needed!
/cc @ajgarlag
@maciekstary, I'm just wondering if it won't create the confusion that Oauth2Client::getRoles()
method doesn't return any roles, since there are ROLE_OAUTH2_*
roles created by the library. The point how oauth roles currently work under the hood is still a mystery to me
@rela589n Good point. What I can only say is that in previous implementation authenticator used League\Bundle\OAuth2ServerBundle\Security\User\NullUser
class and it's getRoles
method returns empty array, too.
Sorry, but I'm pretty busy these days.
Can anyone provide a reproducer? I'd need a minimal Symfony app working with league/oauth2-server-bundle:0.8
without a user provider.
Hi, I've tried to prepare a reproducer (based on https://github.com/dwgebler/OAuth2ServerDemo), available here https://github.com/krkabol/OAuth_reproducer. Includes a test client, but sorry as new in Symfony, from some weird reason the /authorize route does not works :) - hopefully you are able to fix it easily yourself.
I have a similar non-public and when upgrade to 0.9, it falls..
EDIT: SSH key included for instant usage, it is not an unwanted leak
@krkabol thanks. I'll try it ASAP.
The reproducer provided by @krkabol was not using client-credentials. It did not fail with the Uncaught PHP Exception Symfony\Component\Config\Definition\Exception\InvalidConfigurationException: ""api" firewall requires a user provider but none was defined." at MissingUserProvider.php line 31
message.
The problem with that repository was reported in #200. I've opened #201 to fix documentation.
I still need a reproducer for the original error reported in this issue.
Bundle setup docs https://github.com/thephpleague/oauth2-server-bundle/blob/58d4b11a5f75dd049d613871e6a3a3a367cbd976/docs/basic-setup.md does not say anything about setting a user provider for a firewall. I get exception
Uncaught PHP Exception Symfony\Component\Config\Definition\Exception\InvalidConfigurationException: ""api" firewall requires a user provider but none was defined." at MissingUserProvider.php line 31
My security.yaml (same as in docs):