Symfony 5.4 trouble setting up drenso/symfony-oidc-bundle - symfony

Im trying to set up an open id connection with this bundle https://github.com/Drenso/symfony-oidc. Did the first step of configuration
drenso_oidc:
#default_client: default # The default client, will be aliased to OidcClientInterface
clients:
default: # The client name, each client will be aliased to its name (for example, $defaultOidcClient)
# Required OIDC client configuration
well_known_url: '%env(OIDC_WELL_KNOWN_URL)%'
client_id: '%env(OIDC_CLIENT_ID)%'
client_secret: '%env(OIDC_CLIENT_SECRET)%'
# Extra configuration options
#redirect_route: '/login_check'
#custom_client_headers: []
# Add any extra client
#link: # Will be accessible using $linkOidcClient
#well_known_url: '%env(LINK_WELL_KNOWN_URL)%'
#client_id: '%env(LINK_CLIENT_ID)%'
#client_secret: '%env(LINK_CLIENT_SECRET)%'
Variables are also set in my .env.
when i enable oidc in my security.yml, this happen :
here's my security.yml :
security:
enable_authenticator_manager: true
password_hashers:
App\Entity\BackUser: auto
App\Entity\FrontUser: auto
providers:
users:
chain:
providers: [back_users, front_users]
back_users:
entity: { class: App\Entity\BackUser, property: username }
front_users:
entity: { class: App\Entity\FrontUser, property: email }
role_hierarchy:
ROLE_SUPER_ADMIN: ROLE_ADMIN
ROLE_ADMIN: [ROLE_REDACTOR, ROLE_ALLOWED_TO_SWITCH]
ROLE_REDACTOR: ROLE_READER
ROLE_READER: ROLE_USER
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
back:
context: global_context
pattern: ^/back
#anonymous: ~
user_checker: App\Security\Checker\UserChecker
provider: back_users
switch_user:
provider: users
role: CAN_SWITCH_USER
form_login:
provider: users
check_path: back_security_login
login_path: back_security_login
#csrf_token_generator: security.csrf.token_manager
enable_csrf: true
default_target_path: back_static_index
success_handler: App\Security\Handler\LoginSuccessHandler
failure_handler: App\Security\Handler\LoginFailureHandler
logout:
path: back_security_logout
target: back_security_login
handlers:
- App\Security\Handler\LogoutHandler
front:
context: global_context
pattern: ^/
oidc: ~
#anonymous: ~
user_checker: App\Security\Checker\UserChecker
provider: front_users
switch_user:
provider: users
role: CAN_SWITCH_USER
# form_login:
# provider: users
# check_path: front_index
# login_path: front_index
# #csrf_token_generator: security.csrf.token_manager
# enable_csrf: true
# default_target_path: front_index
# success_handler: App\Security\Handler\LoginSuccessHandler
logout:
path: front_security_logout
target: front_index
handlers:
- App\Security\Handler\LogoutHandler
I just cant figure out why this happen. If someone has a clue or has already used this package and may know what i'm doing wrong?
wishing y'all a good day

Related

How to Use multiple User Providers in symfony 5. How to chain it?

UPADATED CODE and PROBLEM :
I use symfony Symfony 5.3.6.
I have two kinds of users: company & candidate.
I'd like to make them able to autenticate on their side. 2 forms are coming from front end. ( but for the moment no forms).
I use lexik_jwt_authentication.jwt_token_authenticator to authenticate my both kind of users.
This is the first time I try to code for 2 providers in my security.yaml.
When I had only one , it worked. When i added company, it doesnt anymore.
Here is my updated code in my security.yaml :
security:
# https://symfony.com/doc/current/security/experimental_authenticators.html
enable_authenticator_manager: true
# https://symfony.com/doc/current/security.html#c-hashing-passwords
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
App\Entity\Candidate:
algorithm: auto
App\Entity\Company:
algorithm: auto
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
app_candidate_provider:
entity:
class: App\Entity\Candidate
property: email
app_compagny_provider:
entity:
class: App\Entity\Company
property: email
app_users:
chain:
providers: ['app_candidate_provider', 'app_compagny_provider']
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/api/login
stateless: true
anonymous: false
json_login:
check_path: /api/login
username_path: email
password_path: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/api/
stateless: true
anonymous: false
provider: app_users
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
main:
# anonymous: lazy
lazy: true
provider: app_user_provider
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#firewalls-authentication
# 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 }
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/candidates, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/api/company, roles: IS_AUTHENTICATED_FULLY }
Now, my message error is : "Not configuring explicitly the provider for the "json_login" listener on "login" firewall is ambiguous as there is more than one registered provider.."
i have followed this thread :
Not configuring explicitly the provider for the "guard" listener on "x" firewall is ambiguous as there is more than one registered provider
By remplacing
api:
pattern: ^/api/
stateless: true
anonymous: false
provider: app_users
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
with
api:
pattern: ^/api/
stateless: true
anonymous: false
provider: 'app_candidate_provider'
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
But still doesnt work
Do you have an idea where i make a mistake ?
EDIT : the final answer told by #mcsky is the good one :
security:
# https://symfony.com/doc/current/security/experimental_authenticators.html
enable_authenticator_manager: true
# https://symfony.com/doc/current/security.html#c-hashing-passwords
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
App\Entity\Candidate:
algorithm: auto
App\Entity\Company:
algorithm: auto
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
app_candidate_provider:
entity:
class: App\Entity\Candidate
property: email
app_compagny_provider:
entity:
class: App\Entity\Company
property: email
app_users:
chain:
providers: ['app_candidate_provider', 'app_compagny_provider']
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/api/login
stateless: true
provider: app_users
anonymous: false
json_login:
check_path: /api/login
username_path: email
password_path: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/api/
stateless: true
anonymous: false
provider: app_users
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
main:
# anonymous: lazy
lazy: true
provider: app_candidate_provider
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#firewalls-authentication
# 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 }
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/candidates, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/api/company, roles: IS_AUTHENTICATED_FULLY }
You can't define one user provider with multiple classes as a configuration. It is not designed to work like this. Symfony executes this class Symfony\Bridge\Doctrine\Security\User\EntityUserProvider under the wood, as you can see it work with property and email string only.
So I suggest you define two different user providers, one per class type.
So can you try this configuration?
providers:
app_candidate_provider:
entity:
class: App\Entity\Candidate
property: email
app_compagny_provider:
entity:
class: App\Entity\Company
property: email
app_users:
chain:
providers: ['app_candidate_provider', 'app_compagny_provider']
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/api/login
stateless: true
provider: app_users
anonymous: false
json_login:
check_path: /api/login
username_path: email
password_path: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/api/
stateless: true
anonymous: false
provider: app_users
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
Let me know if something isn't clear or don't work

Symfony 5 Invalid firewall "api": user provider "app_user_provider" not found

When i add a new firewall for use api Authentication , i get this fail:
Invalid firewall "api": user provider "app_user_provider" not found.
how i can fix this fail?
security:
encoders:
App\Entity\User:
algorithm: bcrypt
cost: 4
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
in_memory: { memory: ~ }
proveedor:
entity:
class: App\Entity\User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: true
form_login:
login_path: login
check_path: login
provider: proveedor
default_target_path: tasks
logout:
path: /logout
target: /
api:
pattern: ^/api
anonymous: lazy
provider: app_user_provider
guard:
authenticators:
- App\Security\TokenAuthenticator
In your firewall named 'api', you specify 'app_user_provider' but in it is not present in the providers list.
In the providers list, you have: in_memory and proveedor.
Try to replace app_user_provider by proveedor.
If the provider allow you to get your user, it should work.

Symfony 4 : How to have multi providers for user/admin in firewall?

I can not have two different providers for user and admin with two different forms
I want to have two firewalls, for users and for admins. I created two different providers linking two different entities. I can log in as a user, but never as Admin .. I do not understand what I need to add more.
Another thing, I know that there is app.user. But is there also app.admin? In order to have two completely separate accounts on two different firewalls?
security:
providers:
user_provider:
entity:
class: App\Entity\User
property: username
admin_provider:
entity:
class: App\Entity\Admin
property: username
chain_provider:
chain:
providers: [user_provider, admin_provider]
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
provider: user_provider
anonymous: true
logout:
path: /logout
target: /login
remember_me:
secret: '%kernel.secret%'
lifetime: 604800 # 1 week in seconds
path: /
form_login:
login_path: /login
check_path: /login
backoffice:
pattern: ^/backoffice
provider: admin_provider
logout:
path: /backoffice/logout
target: /backoffice/login
form_login:
login_path: /backoffice/login
check_path: /backoffice/login
access_control:
- { path: ^/backoffice/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/backoffice, roles: ROLE_ADMIN }
- { path: ^/mon-compte, roles: ROLE_USER }
encoders:
App\Entity\User:
algorithm: bcrypt
cost: 12
App\Entity\Admin:
algorithm: bcrypt
cost: 12
I have null error when I call $authenticationUtils->getLastAuthenticationError()
Switch firewalls order, so the main firewall is the last one.
Symfony uses only one firewall per request and it's the first matched with the pattern. So in your case it's using main firewall for ^/backoffice urls too because /backoffice matches ^/ pattern.
I'm not sure if it will solve all your issues here, but you need to do this in order to really use backoffice firewall.
Regarding app.user and app.admin - no, there's no app.admin. Admin is a user too, so when you'll be logged in as admin, you'll get its entity with app.user
Here is my updated security.yaml :
security:
providers:
admin_provider:
entity:
class: App\Entity\Admin
property: username
user_provider:
entity:
class: App\Entity\User
property: username
chain_provider:
chain:
providers: [user_provider, admin_provider]
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
backoffice:
pattern: ^/backoffice
provider: admin_provider
anonymous: true
logout:
path: admin.logout
target: admin.login
form_login:
login_path: admin.login
check_path: admin.login
default_target_path: admin.index
main:
pattern: ^/
provider: user_provider
anonymous: true
logout:
path: logout
target: login
remember_me:
secret: '%kernel.secret%'
lifetime: 604800 # 1 week in seconds
path: /
form_login:
login_path: login
check_path: login
access_control:
- { path: ^/backoffice/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/backoffice, roles: ROLE_ADMIN }
- { path: ^/mon-compte, roles: ROLE_USER }
encoders:
App\Entity\User:
algorithm: bcrypt
cost: 12
App\Entity\Admin:
algorithm: bcrypt
cost: 12

How to set correctly two types of user and firewalls on Symfony security?

I'm new to symfony and it is getting really hard to understand the documentation about security. So I'm here in hope that someone can lend me a hand. I've been working on teachers(profesores) and students(alumnos), where each of then can just access to their respective area (/profesores/.* and /alumnos/.*). However, I get the browser login to appear when I access these url, but they don't get the created users from their respective entities.
My security is set as follows:
security:
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
area_profesores:
pattern: /profesores/.*
provider: profesores_desde_bd
switch_user:
role: ROLE_PROFESOR
anonymous: ~
form_login:
check_path: /profesores/login_check
login_path: /profesores/login
logout:
path: /profesores/logout
target: /portada/
area_alumnos:
pattern: /alumnos/.*
provider: alumnos_desde_bd
switch_user:
role: ROLE_ALUMNO
anonymous: ~
form_login:
check_path: /alumnos/login_check
login_path: /alumnos/login
logout:
path: /alumnos/logout
target: /portada/
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
http_basic: ~
access_control:
- { path: ^/profesores, roles: ROLE_PROFESOR}
- { path: ^/alumnos, roles: ROLE_ALUMNO }
- { path: /login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
# https://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
providers:
profesores_desde_bd:
entity:
class: AppBundle\Entity\Profesores
property: username
alumnos_desde_bd:
entity:
class: AppBundle\Entity\Alumnos
property: username
encoders:
AppBundle\Entity\Profesores:
algorithm: bcrypt
cost: 12
iterations: 0
AppBundle\Entity\Alumnos:
algorithm: bcrypt
cost: 12
iterations: 0
Symfony\Component\Security\Core\User\User:
algorithm: bcrypt
cost: 12
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
#http_basic: ~
# https://symfony.com/doc/current/security/form_login_setup.html
#form_login: ~
The answer is:
I need to erase
main:
anonymous: ~
http_basic: ~
since that authentication does not log me in.

FOSUserBundle: Why I get exception on login_check?

I try to configure FOSUserBundle in Symfony 2.7 but I still get "You must configure the check path to be handled by the firewall using form_login in your security firewall configuration." exception.
I searched vendor folder for Security Controller and I found that checkAction throws such exception.
I would like to allow
admin to log into /admin section,
and editors to /editor section.
I use two ways of logging: one is in_memory, and second fos_userbundle. This is my security.yml
encoders:
Symfony\Component\Security\Core\User\User: plaintext
Inpero\PageBundle\Entity\User: bcrypt
# http://symfony.com/doc/current/book/security.html#hierarchical-roles
role_hierarchy:
ROLE_EDITOR: ROLE_USER
ROLE_ADMIN: [ROLE_EDITOR, ROLE_USER]
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
# http://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers
providers:
in_memory:
memory:
users:
admin: { password: pass1, roles: [ 'ROLE_ADMIN' ] }
fos_userbundle:
id: fos_user.user_provider.username
# the main part of the security, where you can set up firewalls
# for specific sections of your app
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
# the login page has to be accessible for everybody
page_login:
pattern: ^/admin/login$
security: false
page_admin:
pattern: ^/admin
form_login:
check_path: my_page_check
login_path: my_page_login
logout:
path: my_page_logout
target: /
editor_login:
pattern: ^/editor/login
security: false
editors:
pattern: ^/editor
form_login:
provider: fos_userbundle
check_path: /editor/login_check
login_path: /editor/login
failure_path: /editor/login
default_target_path: /editor/
always_use_default_target_path: true
#csrf_token_generator: security.csrf.token_manager
# if you are using Symfony < 2.8, use the following config instead:
csrf_provider: form.csrf_provider
logout:
path: fos_user_security_logout
target: /
anonymous: ~
# with these settings you can restrict or allow access for different parts
# of your application based on roles, ip, host or methods
# http://symfony.com/doc/current/book/security.html#security-book-access-control-matching-options
access_control:
- { path: ^/efconnect, role: IS_AUTHENTICATED_REMEMBERED }
- { path: ^/elfinder, role: IS_AUTHENTICATED_REMEMBERED }
- { path: ^/admin, role: ROLE_ADMIN }
- { path: ^/editor, role: ROLE_EDITOR }
What am I doing wrong?

Resources