-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Security] Added LDAP support to Authenticator system #36600
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
After chatting about this, here is my proposal:
For the last part, we would leverage a new tag for ldap: if your ldap service has a tag, it's injected into the listener's locator. This will allow people to write custom authenticators that use LDAP. They would just need to: A) Register the LDAP service |
06d65ef
to
e71a5a3
Compare
3f0e4d9
to
f3b5ca6
Compare
$ldapBadge = $passport->getBadge(LdapBadge::class); | ||
if ($ldapBadge->isResolved()) { | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess technically this should be moved before the if statement above? In theory, someone could resolve this and not even have a PasswordCredentials? Not sure why, but I think it makes sense higher.
|
||
/** @var PasswordCredentials $passwordCredentials */ | ||
$passwordCredentials = $passport->getBadge(PasswordCredentials::class); | ||
if ($passwordCredentials->isResolved()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would mean that LdapBadge
is NOT resolved, but PasswordCredentials
IS resolved. I would prefer to throw an exception: this is an unexpected case: a resolved PasswordCredentials
is basically the same (at this point) as NO PasswordCredentials
since a resolved PasswordCredentials
has a null password.
2c49273
to
20962e6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is ready - test failures are unrelated
Thank you @wouterj. |
The last missing authenticator in the new system 🎉
I have no experience with LDAP at all and I didn't succeed in setting up a server locally. So I can't test whether this works, but the unit test works (and also tested in a real app, while adding a
dd()
call in the listener).I want to share with you the current state of Security LDAP, how this PR implements it and a possible other solution (which I think I would prefer most). Is there anyone who can share their opinions on this? (hopefully @weaverryan and @csarrazi can share their opinion, as they have most experience on this topic)
Current Solution: An LDAP authentication provider + duplicated
SecurityFactory
classesLDAP is done in one centralized authentication provider. This provider is configured by security factories for each core factory (e.g.
form_login
becomesform_login_ldap
,http_basic
becomeshttp_basic_ldap
).Implementation in this PR: A listener is executed before the default
VerifyCredentialsListener
, to verifyPasswordCredentials
This listener must be configured for each specific authenticator wanting to use LDAP. This is a technique similar to (1). It's a bit difficult to use this for your own authenticator (you need to configure a custom listener service) and still needs the duplicated factory classes
Proposal: Introduce a
LdapCredentials
class and always register a listenerIf an authentictor returns
LdapCredentials
, it'll be checked using the LDAP verification listener. This is the easiest for custom authenticators and would remove the duplicated factories, I can imagineform_login
getting a newldap
sub option to configure the settings.The main disadvantage (I think) is that we would need to make
LdapCredentials
configure all options: ldap service, dnString, searchDn, searchPassword & queryString. Especially passing around the ldap service seems a bit weird. The main questions here are: Is it weird to pass all these things in theLdapCredentials
? And, do we really need to support having multiple LDAP configuration sets for different authenticators? Or can we e.g. add a globalsecurity.ldap
configuration, that registers the listener for all authenticators returningLdapCredentials
?