Open jasonpeltzer opened 2 years ago
Hi! Just playing with a fresh install of Symfony 5.4 and Oauth2-server-bundle 0.3.0 (php v, 7.4). It works well up to the stage of using custom authenticators. For now i can issue tokens via api. But when i add to to security.yaml something like that:
main:
...
custom_authenticators:
- League\Bundle\OAuth2ServerBundle\Security\Authenticator\OAuth2Authenticator
entry_point: form_login
test:
pattern: ^/test
oauth2: true
stateless: true
framework crashes with the "title" error.
In vendor/league/oauth2-server-bundle/src/Resources/config/services.php we have interface definition like that:
->set('league.oauth2_server.authenticator.oauth2', OAuth2Authenticator::class)
->args([
service('league.oauth2_server.factory.psr_http'),
service(ResourceServer::class),
abstract_arg('User Provider'),
abstract_arg('Role prefix'),
])
As a workaround i declared service('Symfony\Component\Security\Core\User\UserProviderInterface') instead of abstract 'User Provider'. So now i can access resource servers via token authentification with no errors. Alas i'm not sure that it's a "right" way.
Some points are still not clear for me:
I tried to track down the error, but it's way TOO much information for novice like me (i'm not a Symfony pro nor php coder).
Any advise will be very welcome.
Thanks!
Why are you using custom_authenticators
over oauth2: ~
in the main
firewall?
It worked with Guard Security and the Trikoder libraries. I'm still using a custom authenticator as I need to intercept certain requests that contain an access_token in the url and convert it to a bearer token so it was an artifact of that. After reviewing the documentation I did find it tucked deep in the Basic Setup, so it's my fault for not finding it originally.
Thank you, this was not an obvious fix!
Below is a working example of using custom authenticators alongside the oauth2 bundle.
Setting oauth2: true
is enough to activate oauth2 from the bundle and can be used at the same time as custom_authenticators
. The order of the firewalls is important. I had to make sure the 'main' firewall came after the 'api' firewall in my set up for it to all work properly.
I am using the oauth2 authorization code grant for the API as well as a custom API key authenticator as an alternative authentication method for the API. The login form used by the authorization grant uses a custom authenticator that works with a WordPress user database.
Hope that helps!
security:
enable_authenticator_manager: true
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
providers:
users:
entity:
# the class of the entity that represents users
class: 'App\Entity\User'
# the property to query by - e.g. email, username, etc
property: 'email'
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
api_token:
pattern: ^/token$
security: false
api:
pattern: ^/api
security: true
stateless: true
oauth2: true
provider: users
custom_authenticators:
- App\Security\ApiKeyAuthenticator
main:
security: true
lazy: true
provider: users
custom_authenticators:
- App\Security\LoginFormAuthenticator
logout:
path: logout
# where to redirect after logout
target: login
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#the-firewall
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/authorize, roles: IS_AUTHENTICATED_REMEMBERED }
- { path: ^/api/docs, roles: PUBLIC_ACCESS }
- { path: ^/api, roles: ROLE_USER }
I have the problem with Symfony 6.1 and bundle 0.4 right now. Everything seems to be correct but firewall won't trigger... I can generate new client token but it has never been "requested" for example for following path: /api/v1/users. I dont know where is the problem. Make everything that written in the docs but without success. Can somebody help me with it or how i can debbug it?
This is Firewall:
security:
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
# password_hashers:
# Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
enable_authenticator_manager: true
providers:
users_in_memory: { memory: null }
firewalls:
api_token:
pattern: ^/token$
security: false
api:
pattern: ^/api
security: true
stateless: true
oauth2: true
main:
security: true
lazy: true
provider: users_in_memory
# dev:
# pattern: ^/(_(profiler|wdt)|css|images|js)/
# security: false
# main:
# lazy: true
# provider: users_in_memory
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#the-firewall
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
#
#when@test:
# security:
# password_hashers:
# # By default, password hashers are resource intensive and take time. This is
# # important to generate secure password hashes. In tests however, secure hashes
# # are not important, waste resources and increase test times. The following
# # reduces the work factor to the lowest possible values.
# Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
# algorithm: auto
# cost: 4 # Lowest possible value for bcrypt
# time_cost: 3 # Lowest possible value for argon
# memory_cost: 10 # Lowest possible value for argon
Bundle Config:
league_oauth2_server:
authorization_server: # Required
# Full path to the private key file.
# How to generate a private key: https://oauth2.thephpleague.com/installation/#generating-public-and-private-keys
private_key: '%kernel.project_dir%/var/oauth/private.key'
# Passphrase of the private key, if any
private_key_passphrase: null
# The plain string or the ascii safe string used to create a Defuse\Crypto\Key to be used as an encryption key.
# How to generate an encryption key: https://oauth2.thephpleague.com/installation/#string-password
encryption_key: 'YXqniAl0r3BierGCkJh55IQ3CF3ddELC+0DdOgdEzPQ='
# The type of value of 'encryption_key'
encryption_key_type: plain # One of "plain"; "defuse"
# How long the issued access token should be valid for.
# The value should be a valid interval: http://php.net/manual/en/dateinterval.construct.php#refsect1-dateinterval.construct-parameters
access_token_ttl: PT1H
# How long the issued refresh token should be valid for.
# The value should be a valid interval: http://php.net/manual/en/dateinterval.construct.php#refsect1-dateinterval.construct-parameters
refresh_token_ttl: P1M
# How long the issued auth code should be valid for.
# The value should be a valid interval: http://php.net/manual/en/dateinterval.construct.php#refsect1-dateinterval.construct-parameters
auth_code_ttl: PT10M
# Whether to enable the client credentials grant
enable_client_credentials_grant: true
# Whether to enable the password grant
enable_password_grant: true
# Whether to enable the refresh token grant
enable_refresh_token_grant: true
# Whether to enable the authorization code grant
enable_auth_code_grant: true
# Whether to require code challenge for public clients for the auth code grant
require_code_challenge_for_public_clients: true
# Whether to enable access token saving to persistence layer (default to true)
persist_access_token: true
resource_server: # Required
# Full path to the public key file
# How to generate a public key: https://oauth2.thephpleague.com/installation/#generating-public-and-private-keys
public_key: '%kernel.project_dir%/var/oauth/public.key'
scopes:
# Scopes that you wish to utilize in your application.
# This should be a simple array of strings.
available: [ default ]
# Scopes that will be assigned when no scope given.
# This should be a simple array of strings.
default: [ default ]
# Configures different persistence methods that can be used by the bundle for saving client and token data.
# Only one persistence method can be configured at a time.
persistence: # Required
doctrine:
# Name of the entity manager that you wish to use for managing clients and tokens.
entity_manager: default
# Set a custom prefix that replaces the default 'ROLE_OAUTH2_' role prefix
role_prefix: ROLE_OAUTH2_
client:
# Set a custom client class. Must be a League\Bundle\OAuth2ServerBundle\Model\Client
classname: League\Bundle\OAuth2ServerBundle\Model\Client
Routes & Bundles same as in docs.
I also have this problem. "oauth2: true" is active on the firewall. When accessing the route, I can see in the debugger that the firewall context is loaded, but the authenticator for the bearer token is never run.
Trying to specify League\Bundle\OAuth2ServerBundle\Security\Authenticator\OAuth2Authenticator under custom_authenticators gives the title error.
edit: This is on Symfony 6.1. I would assume something changed in the framework with regards to running authenticators in the way that was originally set up for this library.
Same issue here, migrating to SF6.4 from SF5.4
Just recently tried to make the move from trikoder over to these packages, have "successfully" gotten v0.1.2 working, but when I try to use v0.2.0 or v0.3.0 I get recipe issues and then when I try to run the application I get the error: "Argument 3 of service "league.oauth2_server.authenticator.oauth2" is abstract user provider".
This seems to be an issue with Symfony 5.3/5.4, and is definitely a blocker to getting Symfony 6 working!
Thanks