[GH-ISSUE #145] Add LDAP auth support #108

Closed
opened 2026-02-25 23:33:27 +03:00 by kerem · 10 comments
Owner

Originally created by @ynsta on GitHub (Aug 20, 2019).
Original GitHub issue: https://github.com/go-shiori/shiori/issues/145

Hello,

I would like to contribute to add ldap auth support in your project.

@RadhiFadlillah do you plan to merge soon your ramadhan branch, if not I'll do a PR into this branch ?

I'll need to add a some config options (ldap server, port, tls, search string, ...) I think a shiori.toml file should be a fine solution.

Regards

Originally created by @ynsta on GitHub (Aug 20, 2019). Original GitHub issue: https://github.com/go-shiori/shiori/issues/145 Hello, I would like to contribute to add ldap auth support in your project. @RadhiFadlillah do you plan to merge soon your ramadhan branch, if not I'll do a PR into this branch ? I'll need to add a some config options (ldap server, port, tls, search string, ...) I think a shiori.toml file should be a fine solution. Regards
Author
Owner

@ynsta commented on GitHub (Aug 21, 2019):

Here is a proposition of configuration to be discussed

version = 1 # config version

[serve]
port = 8080

[sql]
driver = "sqlite3" # possible values "sqlite3", "mysql", "postgres",
connectionString = "file:/srv/shiori/shiori.db?cache=shared&mode=memory"
# Connection strings documentation
# sqlite3 : https://github.com/mattn/go-sqlite3#connection-string
# postgres : https://godoc.org/github.com/lib/pq
# mysql : https://github.com/go-sql-driver/mysql/#dsn-data-source-name

[auth]

  [auth.default]
  enabled = true
  user = "shiori"
  password = "gopher"
  visitor = false

  [auth.sql]
  enabled = true

  [auth.ldap]
  enabled = true
  host = "ldap.example.org"
  port = 389
    [auth.ldap.tls]
    enabled = true
    skipCertificateVerif = false
    thrustedCertificates = [
      "/srv/shiori/certs/ca.pem",
      "/srv/shiori/certs/server.pem"
    ]
    [auth.ldap.bind]
    userDN = "cn=svcuser,ou=users,dc=example,dc=org"
    password = "PASSWORD"

    [auth.ldap.search]
    # filter: Availlable search variables are Group and Login, 
    # Group is replaced by ownerGroupDN and then visitorGroupDN.
    # Login is the provided Login.
    # If a user match a owner, visitor will not be searched.
    base = "ou=users,dc=example,dc=org"
    filter = "(&(memberOf={{.Group}})(|(mail={{.Login}})(sAMAccountName={{.Login}})))"
    ownerGroupDN = "cn=shiori_owners,ou=group,dc=example,dc=org"
    visitorGroupDN = "cn=shiori_visitors,ou=group,dc=example,dc=org"
    
    [auth.ldap.mapping]
    firstname = "givenName"
    lastname = "sn"
    login = "sAMAccountName"
    mail = "mail"
<!-- gh-comment-id:523400345 --> @ynsta commented on GitHub (Aug 21, 2019): Here is a proposition of configuration to be discussed ```toml version = 1 # config version [serve] port = 8080 [sql] driver = "sqlite3" # possible values "sqlite3", "mysql", "postgres", connectionString = "file:/srv/shiori/shiori.db?cache=shared&mode=memory" # Connection strings documentation # sqlite3 : https://github.com/mattn/go-sqlite3#connection-string # postgres : https://godoc.org/github.com/lib/pq # mysql : https://github.com/go-sql-driver/mysql/#dsn-data-source-name [auth] [auth.default] enabled = true user = "shiori" password = "gopher" visitor = false [auth.sql] enabled = true [auth.ldap] enabled = true host = "ldap.example.org" port = 389 [auth.ldap.tls] enabled = true skipCertificateVerif = false thrustedCertificates = [ "/srv/shiori/certs/ca.pem", "/srv/shiori/certs/server.pem" ] [auth.ldap.bind] userDN = "cn=svcuser,ou=users,dc=example,dc=org" password = "PASSWORD" [auth.ldap.search] # filter: Availlable search variables are Group and Login, # Group is replaced by ownerGroupDN and then visitorGroupDN. # Login is the provided Login. # If a user match a owner, visitor will not be searched. base = "ou=users,dc=example,dc=org" filter = "(&(memberOf={{.Group}})(|(mail={{.Login}})(sAMAccountName={{.Login}})))" ownerGroupDN = "cn=shiori_owners,ou=group,dc=example,dc=org" visitorGroupDN = "cn=shiori_visitors,ou=group,dc=example,dc=org" [auth.ldap.mapping] firstname = "givenName" lastname = "sn" login = "sAMAccountName" mail = "mail" ```
Author
Owner

@RadhiFadlillah commented on GitHub (Aug 21, 2019):

Hi @ynsta

@RadhiFadlillah do you plan to merge soon your ramadhan branch, if not I'll do a PR into this branch ?

Yep, I just need to make sure that the old database is still compatible, then I will merge it. If all goes well, maybe at most two days from now the branch will be merged to master.

I would like to contribute to add ldap auth support in your project.

Please bear with me, but this is the first time I heard about LDAP.

If I understand it correctly, LDAP is protocol for accessing directory server. Directory server itself is a type of database that stores information represented as trees of entries instead of tables as usually found in relational database. Therefore, directory server can be considered as a type of NoSQL database.

As any other NoSQL database, one of the strength of directory server is it's really fast at reading or querying a large dataset. Therefore, a common use of LDAP is to provide a central place to store usernames and passwords. This allows many different applications and services to connect to the LDAP server to validate users.

So, from what I understand, by implementing LDAP auth, Shiori can connect into a LDAP server. Therefore, when user login in Shiori, instead of comparing user's data in Shiori's own database, now it will compare the login request with user data that contained in LDAP server.

With that said, I'm wondering what is the use case for this feature ?

I mean, if I understand correctly, LDAP usually used for organization with many registered account. In other hand, I imagine one instance of Shiori usually used by only one or two people, which make the existing database is enough for managing account's data.

Feel free to correct me if I'm wrong.

Thank you !

<!-- gh-comment-id:523486131 --> @RadhiFadlillah commented on GitHub (Aug 21, 2019): Hi @ynsta > @RadhiFadlillah do you plan to merge soon your ramadhan branch, if not I'll do a PR into this branch ? Yep, I just need to make sure that the old database is still compatible, then I will merge it. If all goes well, maybe at most two days from now the branch will be merged to master. > I would like to contribute to add ldap auth support in your project. Please bear with me, but this is the first time I heard about LDAP. If I understand it correctly, **LDAP** is protocol for accessing directory server. **Directory server** itself is a type of database that stores information represented as trees of entries instead of tables as usually found in relational database. Therefore, directory server can be considered as a type of NoSQL database. As any other NoSQL database, one of the strength of directory server is it's really fast at reading or querying a large dataset. Therefore, a common use of LDAP is to provide a central place to store usernames and passwords. This allows many different applications and services to connect to the LDAP server to validate users. So, from what I understand, by implementing LDAP auth, Shiori can connect into a LDAP server. Therefore, when user login in Shiori, instead of comparing user's data in Shiori's own database, now it will compare the login request with user data that contained in LDAP server. With that said, I'm wondering what is the use case for this feature ? I mean, if I understand correctly, LDAP usually used for organization with many registered account. In other hand, I imagine one instance of Shiori usually used by only one or two people, which make the existing database is enough for managing account's data. Feel free to correct me if I'm wrong. Thank you !
Author
Owner

@ynsta commented on GitHub (Aug 22, 2019):

Hello,

The use case is to have some people in my organization that can edit the bookmarks in a group (owner) and all other ones connect as visitor. The main use case is to permits manager to provide all usefull links for new employee in a central place.

But I also plan to have other instances to share some interesting learning materials, blogs, ... inside a team, where all users of this team will be owner.

And by using ldap auth it will permits :

  • to provide access automatically to new user without sharing a visitor account.
  • use the same credential for all the apps in the organization.
  • revoke access to a user done in one place.
  • groups are defined in only one place.

It is simple to implement in go, I already done that in other apps, to authenticate a user the flow is :

  1. Connect to ldap
  2. Optionally start TLS and verify certificates
  3. Bind with the service user (user / pass in configuration)
  4. Search the distinguished name (DN) of the user with the provided login and the search string for owner users in the configuration.
  5. Search the distinguished name (DN) of the user with the provided login and the search string for visitor users in the configuration.
  6. If one DN returned for owner: bind with this DN and the provided password, on success return authenticated as owner.
  7. Else If one DN returned for visitor and none for owner: bind with this visitor DN and the provided password, on success return authenticated as visitor.
  8. Else If none returned for the two searches, perform a dummy bind and return not authenticated.

Note that the flow is organized to always perform the same number of search and bind operations to prevent user guessing by timing attacks.

I plan to have some time this week end to do it. If not merged I'll start on your branch and will rebase when your branch will be merged in master.

By the way thank you for you project, I find it very interesting and might be interested to contribute to some other parts in my free time.

Regards,

<!-- gh-comment-id:523889292 --> @ynsta commented on GitHub (Aug 22, 2019): Hello, The use case is to have some people in my organization that can edit the bookmarks in a group (owner) and all other ones connect as visitor. The main use case is to permits manager to provide all usefull links for new employee in a central place. But I also plan to have other instances to share some interesting learning materials, blogs, ... inside a team, where all users of this team will be owner. And by using ldap auth it will permits : - to provide access automatically to new user without sharing a visitor account. - use the same credential for all the apps in the organization. - revoke access to a user done in one place. - groups are defined in only one place. It is simple to implement in go, I already done that in other apps, to authenticate a user the flow is : 1. Connect to ldap 2. Optionally start TLS and verify certificates 3. Bind with the service user (user / pass in configuration) 4. Search the distinguished name (DN) of the user with the provided login and the search string for owner users in the configuration. 5. Search the distinguished name (DN) of the user with the provided login and the search string for visitor users in the configuration. 6. If one DN returned for owner: bind with this DN and the provided password, on success return authenticated as owner. 7. Else If one DN returned for visitor and none for owner: bind with this visitor DN and the provided password, on success return authenticated as visitor. 8. Else If none returned for the two searches, perform a dummy bind and return not authenticated. Note that the flow is organized to always perform the same number of search and bind operations to prevent user guessing by timing attacks. I plan to have some time this week end to do it. If not merged I'll start on your branch and will rebase when your branch will be merged in master. By the way thank you for you project, I find it very interesting and might be interested to contribute to some other parts in my free time. Regards,
Author
Owner

@ynsta commented on GitHub (Sep 6, 2019):

Hello,

I made a PR on this subject.

I also added a Dockerfile.

I made some unit test on the config part but not yet on the LDAP part, I only made manual integration tests.

If I have some more time I'll add some automated tests.

Regards,

<!-- gh-comment-id:528832462 --> @ynsta commented on GitHub (Sep 6, 2019): Hello, I made a [PR](https://github.com/go-shiori/shiori/pull/149) on this subject. I also added a Dockerfile. I made some unit test on the config part but not yet on the LDAP part, I only made manual integration tests. If I have some more time I'll add some automated tests. Regards,
Author
Owner

@RadhiFadlillah commented on GitHub (Sep 7, 2019):

@ynsta thanks!

Sorry for slow response. I just got married last week, so I haven't worked on my PC for last week. I will review it ASAP.

<!-- gh-comment-id:529070444 --> @RadhiFadlillah commented on GitHub (Sep 7, 2019): @ynsta thanks! Sorry for slow response. I just got married last week, so I haven't worked on my PC for last week. I will review it ASAP.
Author
Owner

@ynsta commented on GitHub (Sep 7, 2019):

Hello,

You're welcome.

Dont' worry there is no hurry for the review and congratulation for your wedding.

Regards,

<!-- gh-comment-id:529107331 --> @ynsta commented on GitHub (Sep 7, 2019): Hello, You're welcome. Dont' worry there is no hurry for the review and congratulation for your wedding. Regards,
Author
Owner

@ynsta commented on GitHub (May 16, 2020):

Hello,

I made a new PR #249 without the config part, no all LDAP configuration are given with environment vars.

You could reject the older one #149.

Regards,

<!-- gh-comment-id:629679507 --> @ynsta commented on GitHub (May 16, 2020): Hello, I made a new PR #249 without the config part, no all LDAP configuration are given with environment vars. You could reject the older one #149. Regards,
Author
Owner

@fmartingr commented on GitHub (Feb 5, 2022):

Some work under #249. requires considering if out of scope.

<!-- gh-comment-id:1030712797 --> @fmartingr commented on GitHub (Feb 5, 2022): > Some work under #249. requires considering if out of scope.
Author
Owner

@clach04 commented on GitHub (Jul 13, 2022):

ldap support would be neat, could be used with https://github.com/nitnelave/lldap/ or OpenLDAP, etc.

<!-- gh-comment-id:1183316286 --> @clach04 commented on GitHub (Jul 13, 2022): ldap support would be neat, could be used with https://github.com/nitnelave/lldap/ or OpenLDAP, etc.
Author
Owner

@fmartingr commented on GitHub (Oct 7, 2022):

After further consideration, I'm moving this to a discussion to allow conversation to move on, but there are a lot of things that currently need fixing or a rework to tackle something like LDAP at the moment. Maybe in the future where the auth is more robust and the database engines are refactored we could take a look at this again. Apologies for the delay and a response you were not expecting. Hope we can allow multiple auth engines in the future.

<!-- gh-comment-id:1271336802 --> @fmartingr commented on GitHub (Oct 7, 2022): After further consideration, I'm moving this to a discussion to allow conversation to move on, but there are a lot of things that currently need fixing or a rework to tackle something like LDAP at the moment. Maybe in the future where the auth is more robust and the database engines are refactored we could take a look at this again. Apologies for the delay and a response you were not expecting. Hope we can allow multiple auth engines in the future.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/shiori#108
No description provided.