-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
connector: add LDAP connector #178
Conversation
Please note that this is a Work In Progress and it is probably not ready for merge at this stage. However, I would really like some feedback/reviews on the code. |
Hi @fnordahl, thanks for the contribution! I'm pretty inexperienced with LDAP but at a cursory glance this is looking pretty good. I'll give a closer look later on today, and try configuring it up with an LDAP server. |
Cool @bobbyrullo ! I guess you can use this Docker-image to test: https://github.com/osixia/docker-openldap I have not tested it myself, but it seems good and well documented. Note that you can create the encrypted string to use in the userPassword attribute with the slappasswd command (in reference to the "Add a new user" step in the README.md of the linked repository). I am happy to follow up with more complete/improved code, but would like some pointers as of how the current code looks and fits into the project, and some pointers as to how to address the issues outlined in the commit message. (Callbacks, Registration etc.) Thank you, and I look forward to hear from you! |
hey @fnordahl - I'm having some troubles with the PR - when I register, it seems to recognize my name/password combo, but fails after the "choose an email" part with "There was a problem processing your request." - in the logs I get |
Hey @fnordahl Any updates? :) |
Sure @philips I will be picking this up again shortly. @bobbyrullo Do you have both authAttribute and uidAttribute configured, and do the fields they point to both exist? What does the Identity section of the INFO: Session log-line look like? |
@fnordahl Here's the logs:
|
Here's my connector...looks like I need to have UID attribute set?
|
@bobbyrullo Yes, in the current state of the code you need to have the uidAttribute set. I have written better initialization of the connector on my TODO-list. Some of these settings could probably also often be initalized with good default values, or even autodetection. |
@fnordahl any updates on this one? I'd love to see SSL support for this connector as an additional item in TODO ;-) |
hey @steveej et al: Sorry, for letting this one go - I couldn't get it working quite right, so I gave up on it for a while. I'm going to tinker some more this week and I should have an update soon. |
Some comments on the authentication strategy. Currently the connector uses the user's credentials to bind to the LDAP directory, but this can create issues if the user doesn't have permission to search the directory. Creating an account for the application (in this case dex) seems like a normal strategy. See
And
That would add another field to the connector config.
|
@steveej @bobbyrullo I will try to get some time to look at this again soon! Thank you for the patience and sustained interest :-) |
@ericchiang having a separate configurable LDAP account for this is indeed one of the often used strategies. Your second citation refers to authenticating with the superuser, that is not what we are doing here. However, it is my professional opinion that allowing the individual user to bind to your directory is much more secure. The reason for this is that to authenticate through searching with a separate LDAP account you must give that account read access to the password hashes. In the event that the application with this access is compromised you risk leaking all your password hashes. There will be implemented support for configuring a separate LDAP account for doing search for DN before binding as that DN (i.e. to allow the user to log in with e-mail address or similar). I will look into the possibility for making authentication mode configurable to also include your preference, but I cannot make any promises. |
Wow that's slightly terrifying. Didn't realize search gives you hashes.
|
@ericchiang With the admin user or with a not properly configured ACL you indeed get access to the password hashes. You can configure the ACL so that individual users only have access to authenticate against (bind) or write to the userPassword field, not read it. |
If it's at all a common practice to not allow all users to search (as I believe it is), then we need to allow the option of specifying the searching user. If we don't allow that we are dictating how other people must set up their LDAP systems. |
In this scenario of using a searching user, would it then sufficient to recommend (or even require) that that user has auth but not read access to userPassword hashes? |
I'd say recommend, not require |
8b22620
to
af4ba79
Compare
Updated version:
|
The Travis CI build check fails on the external dependency on the LDAP library. This has passed before, has there been any updates/changes on the CI? @bobbyrullo @ericchiang |
@fnordahl you have to vendor the package using Godeps. That's something we should have better documented anyway, so let me draft something for the entire repo and I'll point you to that. |
4150343
to
5f29db0
Compare
Updated version:
|
@fnordahl awesome work. I don't have any feedback beside my inline note on Going to spin up a LDAP server tomorrow and try this connector out. |
@ericchiang thank you. In regards to the use of ldapConn I'd have to admit that I have not been thorough enough in my research of what dex or the Go language itself does and does not do for you when it comes to concurrency. I guess I got a bit eager to just cross another item off the list at some point. Thank you for pointing it out to me. I will look into implementing a connection pool for the LDAP connections. Failing that we could revert to creating a new connection for each call to Identity() and have the connection pooling be a feature for the next release, depending on how much time we have before we want this released. LDAP connection initialization and tear down tend to be light weight operations for most LDAP servers and workloads out there. I look forward to hear the results of your trials with the connector. |
@fnordahl After looking at the code, I think we should just create a single connection every time for this PR. Remove the ldapConn field on the LDAPConnector and just add a Dail() method to the connector which returns an *ldap.Conn object whenever you need one. Let's get this merged then worry about connection pooling. |
064f1f9
to
89d74d0
Compare
@ericchiang I agree, let's get this baby flying. Updated version:
|
89d74d0
to
ee8d6ba
Compare
Found and reverted one last occurrence of arguments to function call split over multiple lines to be within 79 character width. |
ee8d6ba
to
d692fe9
Compare
Removed the debug log output from the OpenLDAP container during the Travis CI functional-tests. |
d692fe9
to
d78afad
Compare
It seems like one of the test runs were unsuccessfull because of transient failure unrelated to the committed changes. Would it be possible to re-run the test? @ericchiang |
Authentication is performed by binding to the configured LDAP server using the user supplied credentials. Successfull bind equals authenticated user. Optionally the connector can be configured to search before authentication. The entryDN found will be used to bind to the LDAP server. This feature must be enabled to get supplementary information from the directory (ID, Name, Email). This feature can also be used to limit access to the service. Example use case: Allow your users to log in with e-mail address instead of the identification string in your DNs (typically username). To make re-use of HTTP form handling code from the Local connector possible: - Implemented IdentityProvider interface - Moved the re-used functions to login_local.go Fixes dexidp#119
d78afad
to
4d970d5
Compare
Rebased the PR to trigger a re-check. |
LGTM |
connector: add LDAP connector
\o/ |
Authentication is performed by binding to the configured LDAP server using
the user supplied credentials. Successfull bind equals authenticated user.
Optionally the connector can be configured to search before authentication.
The entryDN found will be used to bind to the LDAP server.
This feature must be enabled to get supplementary information from the
directory (ID, Name, Email). This feature can also be used to limit access
to the service.
Example use case: Allow your users to log in with e-mail address instead of
the identification string in your DNs (typically username).
To make re-use of HTTP form handling code from the Local connector possible:
Fixes #119