I want to implement the following authentication scenario in symfony 5:
- User sends a login form with username and password, authentication is processed against an LDAP server
- if authentication against the LDAP server is successful :
- if there is an instance of my
App\Entity\Userthat as the same username as the ldap matching entry, refresh some of its attributes from the ldap server and return this entity - if there is no instance create a new instance of my
App\Entity\Userand return it
- if there is an instance of my
- if authentication against the LDAP server is successful :
I have implemented a guard authenticator which authenticates well against the LDAP server but it's returning me an instance of Symfony\Component\Ldap\Security\LdapUser and I don't know how to use this object to make relation with others entities!
For instance, let's say I have a Car entity with an owner property that must be a reference to an user.
How can I manage that ?
Here is the code of my security.yaml file:
security:
encoders:
App\Entity\User:
algorithm: auto
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\User
property: email
my_ldap:
ldap:
service: Symfony\Component\Ldap\Ldap
base_dn: "%env(LDAP_BASE_DN)%"
search_dn: "%env(LDAP_SEARCH_DN)%"
search_password: "%env(LDAP_SEARCH_PASSWORD)%"
default_roles: ROLE_USER
uid_key: uid
extra_fields: ['mail']
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: true
lazy: true
provider: my_ldap
guard:
authenticators:
- App\Security\LdapFormAuthenticator
I finally found a good working solution. The missing piece was a custom user provider. This user provider has the responsibility to authenticate user against ldap and to return the matching
App\Entity\Userentity. This is done ingetUserEntityCheckedFromLdapmethod ofLdapUserProviderclass.If there is no instance of
App\Entity\Usersaved in the database, the custom user provider will instantiate one and persist it. This is thefirst user connectionuse case.Full code is available in this public github repository.
You will find below, the detailed steps I follow to make the ldap connection work.
So, let's declare the custom user provider in
security.yaml.security.yaml:Now, configure it as a service, to pass some ldap usefull string arguments in
services.yaml. Note since we are going to autowire theSymfony\Component\Ldap\Ldapservice, let's add this service configuration too:services.yaml:Note the arguments of the
App\Security\LdapUserProvidercome from env vars..env:Implement the custom user provider :
App\Security\LdapUserProvider:Configure the firewall to use our custom user provider:
security.yamlWrite an authentication guard:
App\SecurityLdapFormAuthenticator:My user entity looks like this: