Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.7k
[Ldap] LDAP authentication should return a meaningful error when the LDAP server is unavailable#44898
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
| throw$e; | ||
| } | ||
| $this->ldap->bind($this->searchDn,$this->searchPassword); |
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.
We could opt to catchInvalidCredentialsException here in order to throw something more-specific that would indicate it is the search bind credentials (used during enumeration) that are invalid, as opposed to the credentials that the user has provided.
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.
Same inCheckLdapCredentialsListener.php line 77
Point being that throwing theInvalidCredentialsException can be ambiguous in either meaning "user-provided credentials are invalid" or "configured search credentials are invalid"
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.
7ab0611 introduces anInvalidSearchCredentialsException which is thrown when binding fails when using the configured search credentials.
Jayfrown commentedJan 3, 2022 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
@wouterj FWIW, I have the following docker-compose setup for a local LDAP: docker-compose.yml:services:openldap:image:osixia/openldap:1.5.0restart:unless-stoppedenvironment:LDAP_LOG_LEVEL:"256"LDAP_ORGANISATION:${LDAP_ORGANISATION:-Example Inc.}LDAP_DOMAIN:${LDAP_DOMAIN:-example.org}LDAP_BASE_DN:${LDAP_BASE_DN:-"dc=example,dc=org"}LDAP_ADMIN_PASSWORD:${LDAP_ADMIN_PASSWORD:-admin}LDAP_CONFIG_PASSWORD:${LDAP_CONFIG_PASSWORD:-config}LDAP_RFC2307BIS_SCHEMA:"false"LDAP_BACKEND:"mdb"LDAP_TLS:"true"LDAP_TLS_CRT_FILENAME:"ldap.crt"LDAP_TLS_KEY_FILENAME:"ldap.key"LDAP_TLS_DH_PARAM_FILENAME:"dhparam.pem"LDAP_TLS_CA_CRT_FILENAME:"ca.crt"LDAP_TLS_ENFORCE:"false"LDAP_TLS_CIPHER_SUITE:"SECURE256:-VERS-SSL3.0"LDAP_TLS_VERIFY_CLIENT:"demand"LDAP_REPLICATION:"false"KEEP_EXISTING_CONFIG:"false"LDAP_REMOVE_CONFIG_AFTER_SETUP:"true"LDAP_SSL_HELPER_PREFIX:"ldap"tty:truestdin_open:truevolumes: -ldap_data:/var/lib/ldap -ldap_config:/etc/ldap/slapd.d -ldap_certs:/container/service/slapd/assets/certs/ports: -"389:389" -"636:636"phpldapadmin:image:osixia/phpldapadmin:latestenvironment:PHPLDAPADMIN_LDAP_HOSTS:"openldap"PHPLDAPADMIN_HTTPS:"false"ports: -"8080:80"depends_on: -openldapvolumes:ldap_data:ldap_config:ldap_certs: And the following configuration in Symfony: services.yaml:Symfony\Component\Ldap\Ldap:arguments:['@Symfony\Component\Ldap\Adapter\ExtLdap\Adapter']tags:['ldap']Symfony\Component\Ldap\Adapter\ExtLdap\Adapter:arguments: -host:'%env(resolve:LDAP_HOST)%'port:'%env(resolve:LDAP_PORT)%'encryption:'%env(resolve:LDAP_ENCRYPTION)%'options:protocol_version:3referrals:false security.yaml:providers:app_ldap:ldap:service:Symfony\Component\Ldap\Ldapbase_dn:'%env(resolve:LDAP_BASE_DN)%'search_dn:'%env(resolve:LDAP_SEARCH_DN)%'search_password:'%env(resolve:LDAP_SEARCH_PASSWORD)%'default_roles:ROLE_USERuid_key:uidfirewalls:main:provider:app_ldap .env:You'd have to create the rest of the schema by hand, if needed I can try to provide an LDIF. |
carsonbot commentedJan 4, 2022
Hey! I think@karlshea has recently worked with this code. Maybe they can help review this? Cheers! Carsonbot |
Jayfrown commentedMar 22, 2022
@wouterj if there's anything I can do to make reviewing easier, let me know |
Uh oh!
There was an error while loading.Please reload this page.
stof commentedMar 22, 2022
CheckLdapCredentialsListener has 2 modes. Your PR description lets me think that you tested only one of them. |
ec7a0be to58716bbCompareJayfrown commentedMar 22, 2022
@stof Thanks. It is very possible I might have missed something, as I'm not familiar with the two modes you mention. Could you expand on this or send some documentation my way? |
stof commentedMar 22, 2022
I'm not familiar with the ldap part either. But for those 2 modes, see the if/else inside the try/catch you changed |
Jayfrown commentedMar 22, 2022
@stof Thanks. If I understand correctly the difference is when
Basically allowing the LDAP component to search for a given user in multiple OUs instead of simply interpolating the username into the Expand default behavior
Expand query_string behavior
Having said all that, my changes should not impact either scenario apart from what I've already described. However, when I have some more time I will set up a configuration using |
58716bb to8452c7aCompare[`Jayfrown/ldapdev-ldap-server-unavailable`](https://github.com/Jayfrown/ldap/tree/ldap-server-unavailable)is `symfony/ldap 6.1.*` withsymfony/symfony#44898 applied.
[`Jayfrown/ldapdev-ldap-server-unavailable`](https://github.com/Jayfrown/ldap/tree/ldap-server-unavailable)is `symfony/ldap 6.1.*` withsymfony/symfony#44898 applied.
Jayfrown commentedMar 23, 2022
I made anexample application to make it easier to test and verify behavior. The repository includes a docker-compose configuration that spins up an OpenLDAP container, seeds it with some users, and exposes the ports such that the local application can communicate with it. There are a couple of branches to test all permutations (with/without
Branches with this PR applied require Note that after switching to/from branches with this PR applied it is necessary to run @stof I've tested the same scenarios as mentioned in the OP with the |
65aaf0c to7ab0611Compare…LDAP server is unavailable
7ab0611 toad2cc0eComparefabpot commentedMar 29, 2022
Thank you@Jayfrown. |
Return a 500 ISE if the LDAP server is unreachable.
I have tested the following scenarios:
LDAP server unreachable
Adapter/ExtLdap/Connection.phpthrows aConnectionExceptionwhich is not caught, and this results in a 500 ISE shown to the user. In development mode, you see a relevant trace and the correct error hinting to an unreachable LDAP server, and in production mode this wouldn't be shown to the user, and would be logged.LDAP server reachable, with invalid search bind credentials
The
LdapUserProvidertries to search the LDAP directory for the provided user. To search, it tries to authenticate using the (invalid) bind credentials, resulting inAdapter/ExtLdap/Connection.phpthrowing anInvalidCredentialsExceptionwhich is not caught. As this is indicative of a misconfiguration within the application (ie. the app's search bind credentials are wrong, and searching for any user will always fail) I believe a 500 ISE is appropriate.We could opt to catch the
InvalidCredentialsExceptioninside theLdapUserProviderand throw something more specific, to indicate it is the applications search bind credentials that are invalid, as opposed to the credentials the user provided during authentication.LDAP server reachable, with valid search bind credentials, authenticating as an unknown user
As the search bind credentials are valid, the
LdapUserProvidersearches the LDAP directory, finds no entries, and throws aUserNotFoundExceptionwhich results in the authenticator returning{"code":401,"message":"Invalid credentials."}. I believe this is good / expected behavior.LDAP server reachable, with valid search bind credentials, using known user with invalid password
The
ldap/Adapter/ExtLdap/Connection.phpthrows anInvalidCredentialsException. Theldap/Security/CheckLdapCredentialsListener.phpnow catches theInvalidCredentialsException(instead of theConnectionException) and throws aBadCredentialsExceptionsuch that the authenticator returns{"code":401,"message":"Invalid credentials."}LDAP server reachable, with valid search bind credentials, using known user with valid password
The credentials are validated and the user is logged in, everything works as expected