I have a problem with the connection with the friends of symfony and jwt bundle, by default it uses the username to connect only I need to use email.
I first try to change the property in secutiy.yaml but I can't get it to work.
security:
encoders:
App\Entity\User:
algorithm: bcrypt
providers:
entity_provider:
entity:
class: App\Entity\User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/login
stateless: true
anonymous: true
json_login:
check_path: /login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
register:
pattern: ^/register
stateless: true
anonymous: true
api:
pattern: ^/api
stateless: true
anonymous: false
provider: entity_provider
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
Always when I try to connect it asks me for the username.
try :
fos_userbundle:
id: fos_user.user_provider.username_email
Related
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
I'm working with ldaptools-bundle, fosuserbundle in an api endpoint.
My security.yaml looks like this
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
LdapTools\Bundle\LdapToolsBundle\Security\User\LdapUser: plaintext
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
chain_provider:
chain:
providers: [ldap, fos_userbundle]
fos_userbundle:
id: fos_user.user_provider.username_email
ldap:
id: ldap_tools.security.user.ldap_user_provider
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/login
stateless: true
anonymous: true
provider: ldap
json_login:
check_path: /login
username_path: username
password_path: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
guard:
authenticators:
- ldap_tools.security.ldap_guard_authenticator
main:
pattern: ^/
provider: fos_userbundle
stateless: true
anonymous: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: ROLE_USER }
the problem is thath the ldap guard authenticator is not checking the credentials.
When I change the provider to ldap instead fosuser I got a 500 error code in BasePasswordEncoder class, it happens also if I use the chain_provider
Warning: hash_equals(): Expected known_string to be a string, null
given
Is there a miss config or something?
The workflow should be as follow:
The user is authenticated against ldap server
The user is loaded correctly and then lexik takes care of the token generation
Note: The workflow works without ldap and the token is generated.
Thanks in advance!
I use configuration like documentation. This is my security file:
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_ADMIN: [ROLE_USER]
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
login:
pattern: ^/api/login
stateless: true
anonymous: true
json_login:
check_path: /api/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/api
provider: fos_userbundle
stateless: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/api/login_check, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
and my routing file
api_login_check:
path: /api/login_check
When I get in m browser to /api/login_check i get error
Unable to find the controller for path "/api/login_check". The route is wrongly configured.
Any idea?
change your security.yml login firewall configuration with the following:
login:
pattern: ^/api/login
stateless: true
anonymous: true
form_login:
check_path: /api/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
remove login_check path from your access control it should be already configured
- { path: ^/api/login_check, roles: IS_AUTHENTICATED_ANONYMOUSLY }
You need to adjust your access control configuration :
access_control:
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
I am pretty sure you use API Platform for this, if you read the documentation here, you will see that the access control on the login URL use ^/login in the path and not ^/api/login_check
I just tested symfony flex with LexikJWTAuthenticationBundle2.4, I followed here
Error is NotFoundHttpException
Unable to find the controller for path "/login_check". The route is wrongly configured.
do I have to create a controller? not sure!
or what is it like stupidity
this my security file:
security:
encoders:
App\Entity\User:
algorithm: bcrypt
providers:
entity_provider:
entity:
class: App\Entity\User
property: username
users:
id: App\Metier\Provider\UserProvider
firewalls:
login:
pattern: ^/login
stateless: true
anonymous: true
json_login:
provider: users
check_path: /login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
register:
pattern: ^/register
stateless: true
anonymous: true
api:
pattern: ^/api
stateless: true
provider: entity_provider
anonymous: false
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/personnel, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
My route.yml and My private key:
api_login_check:
path: /login_check
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,1F2589373C3622EADA0262E3D18FBA51
thank you in advance for your help
I solved my problem, because I used json_login in firewalls,so we had to do as to authenticate with postman:
{
"username":"bla",
"password":"blabla"
}
I'm trying to use FOSOAuthServerBundle.
From my ios application, I correctly get the token from /oauth/v2/token, I can see in my database the entry in AccessToken and RefreshToken with the correct user_id.
Opening the _profile, I can see I'm authenticated but I'm logged in as anonymous... why this is happening?
When trying to access /secured/api/me, I'm redirected to /login path...
Can somebody help me?
Here my security.yml
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_USER
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
oauth_token:
pattern: ^/oauth/v2/token
security: false
oauth_authorize:
pattern: ^/oauth/v2/auth
# form_login:
# provider: fos_userbundle
# check_path: /oauth/v2/auth_login_check
# login_path: /oauth/v2/auth_login
anonymous: true
api:
pattern: ^/api
fos_oauth: true
stateless: true
anonymous: true
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
login_path: /login
check_path: /login_check
oauth:
resource_owners:
facebook: "/login/check-facebook"
google: "/login/check-google"
login_path: /login
use_forward: false
failure_path: /login
oauth_user_provider:
#this is my custom user provider, created from FOSUBUserProvider - will manage the
#automatic user registration on your site, with data from the provider (facebook. google, etc.)
service: my_user_provider
logout: true
anonymous: true
login:
pattern: ^/login$
security: false
remember_me:
key: "%secret%"
lifetime: 31536000 # 365 days in seconds
path: /
domain: ~ # Defaults to the current domain from $_SERVER
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
- { path: ^/oauth/v2/auth, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/secured, role: [ IS_AUTHENTICATED_FULLY ] }
.
I think you have in your security.yml, under the firewall 'api ' :
//...
api :
// ...
stateless : true
// ...
You have to send the access_token on every request.
Furthermore, if you want to get an authenticated access_token, you have to get it by a request with de parameter "grant_type=password".
With this access_token, your server will recognize the user in each request.
Something like:
PROVIDER_HOST/oauth/v2/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=password&username=USERNAME&password=PASSWORD
(source: OAuth2 Explained: Part 3 - Using OAuth2 With Your Bare Hands)