Skip to content
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

LDAP authentication #274

Open
raffis opened this issue Mar 5, 2020 · 27 comments
Open

LDAP authentication #274

raffis opened this issue Mar 5, 2020 · 27 comments
Labels
feat New feature or request.
Milestone

Comments

@raffis
Copy link

raffis commented Mar 5, 2020

Describe the solution you'd like

I would like to see the possibility of ldap authentication. Following points should be considered:

  • Mapping of attributes
  • LDAP bind with binddn and rebind with an identity found from an ldapsearch to validate authentication
  • Might be similar to the password flow since we also require an identity and a password for simple bind (not talking about sasl)

Options:

  • RFC 3062 password change may be implemented. Optional since such a thing is usually handled elsewhere if someone uses ldap

Additional context
https://github.com/go-ldap/ldap

@aeneasr
Copy link
Member

aeneasr commented Mar 5, 2020

LDAP as an up or downstream? Meaning that we should allow LDAP as an identity pool for Kratos, or that Kratos is able to become an LDAP server?

@raffis
Copy link
Author

raffis commented Mar 5, 2020

Well the seccond would be awesome but I don't really see a point in that since ldap is quite complex and there are already pretty good ldap servers out there.

Kratos should be able to talk to one or more external ldap servers to authenticate users.

@aeneasr
Copy link
Member

aeneasr commented Mar 5, 2020

Agreed - tracking but with an undefined milestone as we have to get other things done first.

@aeneasr aeneasr added the feat New feature or request. label Mar 5, 2020
@aeneasr aeneasr added this to the unplanned milestone Mar 5, 2020
@raffis
Copy link
Author

raffis commented Mar 5, 2020

Usually big enterprises have existing ldap infrastructure and I would like to see a kratos/hydra construct which can authenticate users against it.

@raffis
Copy link
Author

raffis commented Mar 5, 2020

If I have some spare time I can look into this. But did not look at the kratos core yet in detail.

@aeneasr
Copy link
Member

aeneasr commented Mar 5, 2020

Cool! Contributions are always welcomed!

@jiangytcn
Copy link

that would a useful feature for enterprise. I'm evaluating the ory stacks, and now pending on this new feature to support existing ldap servers group.

@aeneasr
Copy link
Member

aeneasr commented Mar 27, 2020

Feel free to start a plan how LDAP integration could be implemented in Kratos, contributions are welcome!

@ZhaoTzuHsien
Copy link

Is there any further progress?

@blufor
Copy link

blufor commented Apr 3, 2021

So, where do I begin...

Probably first with some background on this rather lenghty post. The reason for it is mainly my personality which drives me into practitiong what @jordansissel (author of Logstash) coined as ADD - Anger Driven Development :) And that simply lead me to the decision to put my spare time and hopefully further few lines of code to it.

So in this post I'll go through the currently rather troubled situation with open-source SSO/IDP, some kludgy options available at this time, key architecture questions about this feature that need to be covered and options to be selected. I'll do my best structuring it so we can start constructive discussion probably on Slack. I've joined today, same nickname - @blufor - so you can contact me there. BTW That's the main goal of this post; to get things moving so the coding can start ASAP - while COVID effects still last and there's spare time ;)

There are some references to links and notes that further explain certain statements or provide more background. It looks like this [a].

SSO and Identity isn't new

....but it still sucks :(

I remember more than 15 years ago, I've been tasked with deploying and delivering Sun Access Manager to a customer [b]. Really massive enterprise piece of Java shit that is luckily already in silicon heaven. It supported LDAP as IdP and Kerberos as SSO.

Since then things have evolved, but rather in the sense of quantity. There are quite a lot of projects that provide both SSO integrations with standardized (cert, user/pass, and modern auth mechanisms. And not just paid, but also "freemium" (but sometimes free version lacks something you need) but also open-source. The problem is - almost all of them are in fsckin Java! [c].

But however those solutions might be, most of them provide login integration Kerberos and/or LDAP. And these two are gonna stay with us for some time. Many other services and tools integrate them and LDAP is generally a good battle-tested technology to be source of truth for identity verification and data lookup.

The Bill Gates conspiracy

The reson, why i think this feature should have its priority increased is the current reality. Lots of the people asking about it is Microsoft's good business model. The Active Directory has been (and still is) requirement of many companies, including startups. From my last 5 customers only 1 didn't have Windows Domain but that changed some time after I left and the company grew a bit more.

Why is that? Well, almost any successful company comes to a point when it has increasing amount of employees. And they need computers to work on. From what current market offers, Microsoft has been winning for a long time, so far thanks to lower price [d] and the capability of managing the machines centrally, which gives them ticks for certifications in future and is overall more complete solution (quality aside...).

Now one Win Server license also hasn't been that expensive either. Plus for some time, you have their sales reps massively pushing their Cloud services with crazy initial discount (I've heard of 0$ bills up to 1yr). Those Cloud services of course integrate with on-prem Active Directory nicely. So compared to Google offerings, you're getting the same services basically, but M$ also packs workstation management in it. Like it or not, it just simply is a complete package.

[e]

Current Golang LDAP integrations

Authelia

Really neatly looking Go app with significant backing that integrates a lot, however the OIDC provider is still WIP. Anyways their LDAP integration in Go might serve as a point of reference [ldap_connection_factory.go, ldap_user_provider.go]

Uses go-ldap/ldap/v3. Looks like it uses Redis (and maybe more) to cache of selected LDAP fields of user objects [link]. Also seems like it provides flow to reset password (not sure it covers LDAP)

Werther

Identity Provider in itself that uses LDAP as data backend for login identities. Supports Login and Consent flows only. Has UI, integrates with ORY Hydra. Basically looks like Kratos with fewer features and added customizable UI (go-template)

No updates for some time, however recently got updated with go-ldap/ldap/v3

Feature proposal

What

  • Use go-ldap/ldap/v3
    • Implement both generic LDAP and M$ AD (as most of their stuff... it has its quirks)
    • both plain and TLS (emit warning on startup about being insecure, when so)
    • simple bind auth for now
  • Create model for connection configuration
  • Extend the Identity Data Model with new ldap credential type
    • identifiers should be: mail, uid (possibly sourced form sAMAccountName attribute)
    • config should contain reference to the LDAP connection config id and LDAP account's dn
  • Somehow implement syncing the data from LDAP to Identity traits
    • shouldn't be editable for now, the only source of truth for this traits is LDAP
  • Implement workflows for
    • Login using LDAP auth for linked identity
    • Registration using first LDAP auth login (need to provide both mail and one of uid or sAMAccoutName)

How?

Some of the previous crucial points need some further decisions to be made and I'd love ie @raffis or @aeneasr to voice their opinions and thoughts.

Create model for connection configuration

Questions:

  • Should be configurable via API call or in config file?
  • Should there be only one LDAP backend or multiple?

Somehow implement syncing the data from LDAP to Identity traits

This one is probably the the most work to be done.

First let's talk about syncing in itself. The necessity of a way of linking the data from LDAP is undisputable. Than means that some sort of unique LDAP identifiers needs to be saved into the Kratos Identity Object. However LDAP is quite often used as configuration tool for authorization by using group membership. This often changes and those changes need to be refrected in the identity traits. Most of the implementations I've checked (Keycloak, Authelia, Gluu,...) have some sort of background syncing. There are two approaches:

  • Full periodic sync of all LDAP users that match a filter defined in config (Keycloak does that)
  • Only periodically sync each user, that has existing LDAP type credential link (Authelia does that AFAIK)

Each has its own treats:

The first one obviously becomes a problem with large user bases. Can be mitigated a little by using multiple Kratos instances, each with different seach base to do a sort of "sharding". Also maybe it can possibly be implemented outside of Kratos and doing the updates via API.

The second one wouldn't grow so rapidly and the periodic data sync could be linked to each account separately, providing equal distribution of sync interval starting points (based on identity update time) across the user-base. This would mean at least +1 a sync goroutine for each LDAP linked account...

Regarding the RFC3062 password modify - It certainly would be nice, however I don't think it really has a high priority. As mentioned - having LDAP usuallu means having coverd management SOPs, like password change, or generic attribute update (surname + martial status, home address, gender...). The latter is IMHO out of scope of Kratos... but I might be wrong

Questions:

  • _Which method of syncing to pick?
  • Is it possible/wise to have the syncer separate from Kratos?
  • How to implement the syncing background worker? Havent found this iterative background pull processing pattern in the code so far.
  • Now if I understand this correctly, the custom values should end-up in the Traits. But I haven't investigated the code further, How it ends up in the in groups OIDC claim?. Maybe I can be referred to an URL that would clarify what/if something needs to be done there?
  • Another thing regarding traits - those can be self-modified by each authenticated user, however this would be unnecessary, generating traffic and confusing users when overwritten after sync interval. Can some traits be something like system-level (=read-only)?
  • Should using LDAP link disqualify the current user/password auth method for the identity?

Registration using first LDAP auth login

This would be valid only when not using/implementing the full sync pattern. Othewise, all of the identities would be created/linked to existing ones during the first LDAP sync.

Questions:

  • Should be done?

Notes:

[a] Hello world

[b] The customer...

...was an office of regional district government in CZ - AFAIK besides governments and global corps in IT, banks, insurance etc, nobody was even considering SSO, mainly because mostly of absent knowledge about security and also the amount of $$$ required back around 2005 in the post-Soviet-bloc parts of Europe.

[c] Java...

...not that it would be bad in itself. It's a great language and VM to efficiently execute operations. However the problem here IMO lays with the ecosystem's long history and its community.

Don't get me wrong - there's a great Java software being made now, look at Elasti.co and their products. It's a breeze to run, operate and maintain. So there must be great Java coders - yes, the reason is in the people creating the software and their culture, policies... On the other hand, look at Jenkins with its massive load of plugins in various deprecation state and bugs in the lots of the remaining ones. The culture of that project is at least questionable.

But if you go deeper, you realize, the problem lays in the sheer scope of what Java provides, the amount of frameworks, protocols (who likes XML + SOAP these days?) and then even languages that JVM can run (like Groovy, Kotlin, but also JRuby, Jython etc.). The immense ammount of complex libs sandwiched together by coders with varying skills into one app can't well in most cases. This obviously relates to one of the longest histories paired with probably the largest subset of people using any programming language.

Now put that image next to Golang, which compared to is Java very new, designed for specific target group to cover mostly basic needs like memory management, concurrency, data handling, system level stuff, network or basic protocols; mainly in an efficient way. Yes,, it took some time to come up with a final proper way for lib management, but the community already brought some cool modern things like oauth, fido, but also Docker, all the Hashicorp stuff, etc.

Which brings us to the alignment of those two narratives, and it's the culture, I don't know how to specify it, some quotes here and there on the website, in tickets... somehow reminds me of the Tao of Hashicorp and I'm absolutely aligned with that philosophy.

NOTE: I have no relation to any of the companies or products mentioned, Just various degrees of experience with using the free/OSS software.

[d] Let's see how Apple stirrs up the market in some time

[e] One more great example...

AD is also packed with RADIUS and CA. Each user and computer has their own cert-key pair and I love to config the companies' network with 802.1x TLS auth on both Wi-Fi and physical network. Each employee always dynamically maps to his VLAN, which is part of a network security zone. This is also mapped via LDAP group membership. And all major network hardware vendors support it without any plans of dropping it. More focus regarding security in those common features is rather on low-lat performance with larger ciphers.

@aeneasr
Copy link
Member

aeneasr commented Apr 4, 2021

Hello @blufor and thank you for the insightful post. Could actually become a blog post? @vinckr could help bring it on the main website so your work isn’t forgotten i. the thousands of github comments!

Also sorry for my short answers - but I’m on mobile for holidays ;)

So first of all we’ve been pushing LDAP back because we didn’t really want to deal with AD and all that stuff. But it’s great to have you here - you did your research and have knowledge- so it looks like there’s no better time to start working on this!

I think the user sync model is nicer - easy to shard (and scale), less work for Kratos - no user filters, and so on!

I imagine the syncer to be a worker like „kratos courier“ which makes it (a) optional and (b) easy to scale and (c) easy to configure using e.g. CLI flags.

For OIDC we merge fields from the POST request (e.g. user consents to ToS) with data from OIDC which is first run through JsonNet for modification. The code for this starts here: https://github.com/ory/kratos/blob/master/selfservice/strategy/oidc/strategy_registration.go#L9

We thought about system level traits but have not implemented them yet. However, adding those would be easy. One question is if we have them in traits or be part of another field (e.g. meta). This probably needs the most thinking!

Alternatively we could also just disable the settings flow for those users? As we would disable other flows too (verification, recovery)?

After thinking about this a bit more: It sounds to me as if all we want here is for a user to exchange their LDAP credentials for a kratos session token? Given that we don’t want registration, recovery, verification, profile updates?

How does 2FA work with LDAP?

@vinckr
Copy link
Member

vinckr commented Apr 9, 2021

Awesome thread!

@aeneasr Could we reformat/expand it a little bit and then publish it under @blufor's name on our blog?
So he gets all the credit for this writeup; I would feel bad to just copy it and put my name there 😅 .

Happy to take care of all the stuff around publishing it, just want to know if you are up to it and if that is generally something we would do?

@aeneasr
Copy link
Member

aeneasr commented Apr 9, 2021

That was the idea :)

@Riz-waan
Copy link

So just curious, would I be able to use my Kratos users and connect a few of them to LDAP, but Kratos being the origin of the accounts? Not sure if it makes sense. Let me try to clarify. Let's say I have a Kratos instance for all my users. A set of those users are employees who need to work with LDAP applications. Is there any way I could use OpenLDAP the same way as something like Hydra, where main user authentication is handled by Kratos. Also, my understanding could be completely flawed, as I just started learning about this stuff.

@aeneasr
Copy link
Member

aeneasr commented Jun 30, 2021

Currently we have no such capabilities in Ory Kratos. I think what this issue refers to is to use LDAP as an upstream provider (like "Sign in With Google") as most companies use e.g. Azure AD for their employee management.

Your proposal would also work, it would mean that Ory Kratos becomes an LDAP server. So instead of issuing tokens or cookies, you could do LDAP queries against Ory Kratos.

Both features are currently not available though.

@haslersn
Copy link

haslersn commented Jul 18, 2021

Given that we don’t want registration, recovery, verification, profile updates?

@blufor @aeneasr If you don't want all of that, then what would be the remaining advantages of Kratos over Werther? Session management (including logout) and 2FA/MFA?

I think for a good user experience it's important to have a single UI where all account-related things are managed, i.e.:

  • Session management (including logout)
  • 2FA/MFA
  • Recovery
  • Profile updates

Of course one can write a UI that has access to both the Kratos API and the LDAP API in order to use the right API for the right task, but I think it would be nicer if the UI only needed access to the Kratos API. Using both APIs would also lead to sync issues, i.e., a user updates something that is done through the LDAP API and this is not immediately synced to Kratos.

I think registration and verification can indeed be left out for now, since in enterprises registration is typically done by admins who can use another UI for administrating the LDAP server.

@strazto
Copy link

strazto commented May 3, 2022

@blufor this would actually be a great blog post ("Quantity over quality - The problem with the evolution of modern SSO" or something) and I'm very happy to see someone acknowledge the clusterdump that is these java based IAM systems.
I thought I was crazy for thinking keycloak actually kinda sucks, because everyone seems to love it

@Pramodamrutkar
Copy link

Is there any further progress?

@neutronth
Copy link

I try to implement this in [1], based on v0.10.1
It's a dirty hack and still lack of code quality, there's no proper code testing and no integration test with kratos-selfservice-ui-node yet, some of code have been copied and pasted from the neighbor strategy, password/oidc, and may not correct implemented.

I did a local integration test with a prepared LDAP (389DS container), it works at least for my expectation.
Hopefully, it may be useful for someone looking for the solution.


[1] https://github.com/neutronth/kratos/tree/strategy-ldap

@zambien
Copy link
Contributor

zambien commented Sep 20, 2022

@neutronth this looks to be a really good starting point for LDAP integration. I've been thinking about creating a sync pipe between LDAP and PostgresDB using PingDataSync (not OSS) or some similar tooling but it would be really nice to be able to use LDAP as the backend. I'm going to play around with this.

@lermana
Copy link

lermana commented Jan 13, 2023

Hi @neutronth and @zambien, happy new year to you both! Thank you for the amazing Ory platform - it's a really key addition to the space. I wanted to ask whether the LDAP integration was something you're actively working on, as this would definitely be of interest to my team. Thank you.

@dhia-gharsallaoui
Copy link

Hello 👋
We are very interested in using LDAP as a backend. Is there any ongoing work or a foundation where we can contribute to adding this feature?
Thank you.

@irisitymichaelgrundberg

Same here, we have a project right now that requires authentication of users that are defined in our customer's on-prem AD. Since we currently use Kratos as authentication backend, it would simplify our architecture if Kratos could talk to the AD using LDAP.

However, we would still require some identities to be created in Kratos, for administrator access in case the connection to AD is down.

We would be willing to contribute with time and code to get this implemented.

@dhia-gharsallaoui
Copy link

Same here!
However, it might not be a good idea, or the current architecture may not be compatible with LDAP. If that's the case, could someone please explain it to us?

@renom
Copy link

renom commented Jan 25, 2024

Any plans to implement this?

@irisitymichaelgrundberg

We have successfully applied the "hack" mentioned in #274 (comment), on top of Kratos v1.0 and it's working fine using OpenLDAP. The goal is to be able to use it in production in a few months, for a customer using Windows Server AD. We also need to have accounts using password strategy in parallel to LDAP strategy (for administration in case the LDAP connection is not working).

@aeneasr It would be nice if we could make a contribution back into the Ory product regarding this, to not have to maintain our own fork of Kratos. Could someone in your team provide any feedback on whether the previously mentioned "hack" is a step in right direction regarding how LDAP integration would be designed? And also provide any feedback what else that should be done for this to be acceptable into Kratos?

@jbguerraz
Copy link

Nice @irisitymichaelgrundberg ! 👍
@aeneasr any input on the matter ? what the community should do with this ldap support ? we're also open to provide time to contribute, we could start from @neutronth's implementation and move it torward release!
what do you think ? any chance that would be suitable ?
Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat New feature or request.
Projects
None yet
Development

No branches or pull requests