Skip to content
This repository has been archived by the owner on May 7, 2024. It is now read-only.

Feature/ldap #238

Merged
merged 3 commits into from
Jul 22, 2018
Merged

Feature/ldap #238

merged 3 commits into from
Jul 22, 2018

Conversation

ammmze
Copy link
Contributor

@ammmze ammmze commented Jul 13, 2018

I've taken LDAP code started here and tested it out and make some additional changes. This addresses #230

Michael Gloystein and others added 3 commits July 6, 2018 21:13
@pantsel
Copy link
Owner

pantsel commented Jul 14, 2018

@ammmze , thanks for the contribution, i'll test it and provide some feedback if needed before merging

@pantsel
Copy link
Owner

pantsel commented Jul 14, 2018

@ammmze , please resubmit the pull req to https://github.com/pantsel/konga/tree/ldap-integration

@ammmze ammmze changed the base branch from master to ldap-integration July 14, 2018 14:18
@ammmze
Copy link
Contributor Author

ammmze commented Jul 14, 2018

@pantsel FYI...this is the docker-compose.yml file I used for testing this:

version: "3"

services:
  ldap:
    image: osixia/openldap:1.2.1
    environment:
      LDAP_ORGANIZATION: Example Inc.
      LDAP_DOMAIN: example.org
      LDAP_ADMIN_PASSWORD: admin

  ldap-ui:
    image: osixia/phpldapadmin:0.7.1
    environment:
      PHPLDAPADMIN_LDAP_HOSTS: ldap
    ports:
      - "${LDAP_UI_PORT:-6443}:443"

  #######################################
  # Postgres: The database used by Kong
  #######################################
  kong-database:
    image: postgres:9.5
    restart: always
    environment:
      POSTGRES_USER: ${POSTGRES_USER:-kong}
      POSTGRES_DB: ${POSTGRES_DB:-kong}
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

  #######################################
  # Kong database migration
  #######################################
  kong-migration:
    image: kong:0.13.1-alpine
    command: "kong migrations up"
    restart: on-failure
    environment:
      KONG_PG_HOST: kong-database
    depends_on:
      - kong-database

  #######################################
  # Kong: The API Gateway
  #######################################
  kong:
    image: kong:0.13.1-alpine
    restart: always
    environment:
      KONG_PG_HOST: kong-database
      KONG_PROXY_LISTEN: 0.0.0.0:8000
      KONG_PROXY_LISTEN_SSL: 0.0.0.0:8443
      KONG_ADMIN_LISTEN: 0.0.0.0:8001
    depends_on:
      - kong-database
    healthcheck:
      test: ["CMD", "curl", "-f", "http://kong:8001"]
      interval: 5s
      timeout: 2s
      retries: 15
    ports:
      - "${KONG_PORT:-8001}:8001"
      - "${API_PORT:-8000}:8000"

  #######################################
  # Konga: Kong GUI
  #######################################
  konga:
    image: pantsel/konga:latest
    build: ./
    restart: always
    environment:
      KONGA_AUTH_PROVIDER: ldap
      KONGA_LDAP_HOST: ldap://ldap:389
      KONGA_LDAP_BIND_DN: cn=admin,dc=example,dc=org
      KONGA_LDAP_BIND_PASSWORD: admin
      KONGA_LDAP_USER_SEARCH_BASE: ou=users,dc=example,dc=org
      KONGA_LDAP_GROUP_SEARCH_BASE: ou=groups,dc=example,dc=org
    depends_on:
      - kong
    ports:
      - "${KONGA_PORT:-1337}:1337"

I just setup the ldap instance via the ui. I setup a users organizational unit and groups organizational unit. Then added a generic user account for John Smith under users. Then added a konga posix group under groups and added jsmith to the group.

In the end it looked something like this:

snapshot of ldap setup

@ammmze
Copy link
Contributor Author

ammmze commented Jul 14, 2018

Hmm...so actually...I just realized the group checking isn't working. Basically it is currently letting any user who has an account login.

@ammmze
Copy link
Contributor Author

ammmze commented Jul 14, 2018

Err...never mind...group checking is working. I had assumed that by setting admin=false, they would not be able to login. But without the appropriate group, they just get a read-only view. Perhaps we should add something additional for a user check, so that you can restrict read-only access as well?

@pantsel pantsel merged commit a19b2f5 into pantsel:ldap-integration Jul 22, 2018
@ammmze ammmze deleted the feature/ldap branch July 23, 2018 16:21
@jeremyjpj0916
Copy link
Contributor

jeremyjpj0916 commented Apr 13, 2022

@ammmze appreciate if you have a casual minute for a 4 year ago thing yah made!

Any idea what is happening here? I am no MS AD LDAP expert by any means...
development mode logs is giving me very little

Using MySQL DB Adapter.
Creating database `konga_stage` if not exists.
(node:7) [DEP0126] DeprecationWarning: timers.active() is deprecated. Please use timeout.refresh() instead.
(node:7) [DEP0096] DeprecationWarning: timers.unenroll() is deprecated. Please use clearTimeout instead.
(node:7) [DEP0095] DeprecationWarning: timers.enroll() is deprecated. Please use setTimeout instead.
debug: Hook:api_health_checks:process() called
debug: Hook:health_checks:process() called
debug: Hook:start-scheduled-snapshots:process() called
debug: Hook:upstream_health_checks:process() called
debug: Hook:user_events_hook:process() called
debug: User had models, so no seed needed
debug: Kongnode had models, so no seed needed
debug: Emailtransport seeds updated
debug: -------------------------------------------------------
debug: :: Wed Apr 13 2022 22:10:24 GMT+0000 (Coordinated Universal Time)
debug: Environment : development
debug: Host        : 0.0.0.0
debug: Port        : 1337
debug: -------------------------------------------------------
(node:7) [DEP0066] DeprecationWarning: OutgoingMessage.prototype._headers is deprecated
debug: ######################################## { user: null }

After a successful login:

image

Was trying to use your LDAP integration logic:

KONGA_AUTH_PROVIDER:
ldap
KONGA_LDAP_HOST:
ldap://ad-ldap.company.com:389
KONGA_LDAP_BIND_DN:
Source: username (konga-ldap-secret)
KONGA_LDAP_BIND_PASSWORD:
Source: password (konga-ldap-secret)
KONGA_LDAP_USER_SEARCH_BASE:
CN=Users,dc=ms,dc=ds,dc=company_value_here,dc=com
KONGA_LDAP_GROUP_SEARCH_BASE:
CN=Users,dc=ms,dc=ds,dc=company_value_here,dc=com
KONGA_ADMIN_GROUP_REG:
^(stargate_self_service_admin|stargate_api_gateway_nonprod)$

Leaving all other vars as default.

For 2 microsoft ad groups to be allowed in as admins(and I know I have those groups as well). Based on the output I am guessing my BIND DN and Pass are good for connecting to the LDAP HOST, my user search base must be working likely too to have gotten by the login. My group search base must likely be the missing component here and why my user ended up as just a "basic" non admin user in limbo...

In some old java code with an LDAP dependency I remember we did it like this to make a list of user groups to eval for authz:

image

@ammmze
Copy link
Contributor Author

ammmze commented Apr 14, 2022

Hey @jeremyjpj0916 ... TBH I'm not much of an LDAP guy either and where I work we never ended up using this. But looking through it, I'm not sure if the group search base is correct. It looks like you have it the same as the user search base. From what it looks like, it looks like it is expecting to do a search in collection of things that returns groups, not users. And then it does adds to the query a filter to filter the groups by the user using the KONGA_LDAP_GROUP_SEARCH_FILTER property mentioned in the readme. In the end, the majority of the ldap stuff is done via the passport-ldapauth plugin, which then in turn passes off stuff to node-ldapauth-fork.

@jeremyjpj0916
Copy link
Contributor

Thanks for your input, yeah I am on the same page I think my group search base is indeed incorrect, will try to get clarification from our internal LDAP management team on what it should look like.

@jeremyjpj0916
Copy link
Contributor

jeremyjpj0916 commented Apr 14, 2022

@ammmze Hmm maybe microsoft ad ldap isn't compatible w this actually I am thinking.

Takes a query like this(via CLI):

ldapsearch -h ad-ldap.company.com -x -b "CN=USERNAME_HERE,CN=Users,dc=ms,dc=ds,dc=COMANY_HERE,dc=com" -W -D "USERNAME@ms.ds.COMPANY.com"
Enter LDAP Password:

To get results of a given user details with a memberOf list(microsoft ad groups):

memberOf: CN=GROUP_NAME_HERE,OU=Cloud-Contacts,OU=Messaging,OU=COMPANY_FIELD,OU=COMPANY,DC
 =ms,DC=ds,DC=COMPANY,DC=com

memberOf: CN=GROUP_NAME_HERE2,CN=Users,DC=ms,DC=ds,DC=COMPANY,DC=com

memberOf: CN=GROUP_NAME_HERE3,OU=Cloud-Contacts,OU=Messaging,OU=COMPANY_FIELD,OU=COMPANY,DC
 =ms,DC=ds,DC=COMPANY,DC=com

If there was then a way per user to get the memberOf list to parse for admin access I imagine the

KONGA_ADMIN_GROUP_REG field would be like:

'^(CN=GROUP_NAME_HERE,OU=Cloud-Contacts,OU=Messaging,OU=COMPANY_FIELD,OU=COMPANY,DC
 =ms,DC=ds,DC=COMPANY,DC=com|CN=GROUP_NAME_HERE2,CN=Users,DC=ms,DC=ds,DC=COMPANY,DC=com)$'

For example giving the first 2 groups in the list admin access. I don't think there is a way in ms ad ldap to lookup all groups and filter on a user context, I think the lookup is by user which will include memberOf groups list. Will confirm this with a team tomorrow. Time to sleep lol.

Edit, maybe I could add KONGA_LDAP_USER_ATTRS: memberOf to the list of things to pull... But then that renders the group search fields useless as all I need is a regex for admins based on a memberOf list match(plus that attributes variable idk if it supports 1 of the attributes being a list of values and not a singular value like uid,uidNumber,givenName,sn,mail all are).

Seems you do have a memberOf bit here: https://github.com/pantsel/konga/pull/238/files#diff-14af2ae5fc48c68823060898a6ddbc038b04a417647f50ae2736f9bc68d33a7cR54 , need to understand how its all connected though.

@jeremyjpj0916
Copy link
Contributor

Well I can search on a specific group by CN Seems:

ldapsearch -h ad-ldap.company.com -x -b "CN=stargate_self_service_admin,CN=Users,dc=ms,dc=ds,dc=COMPANY,dc=com" -W -D "username@ms.ds.company.com"
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <CN=stargate_self_service_admin,CN=Users,dc=ms,dc=ds,dc=company,dc=com> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# stargate_self_service_admin, Users, ms.ds.company.com
dn: CN=stargate_self_service_admin,CN=Users,DC=ms,DC=ds,DC=company,DC=com
objectClass: top
objectClass: group
cn: stargate_self_service_admin
description: Admin group to override LDAP validation checks on user with regar
 ds to Stargate self-service.
member: CN=user1,CN=Users,DC=ms,DC=ds,DC=company,DC=com
member: CN=user2,CN=Users,DC=ms,DC=ds,DC=company,DC=com

distinguishedName: CN=stargate_self_service_admin,CN=Users,DC=ms,DC=ds,DC=company,
 DC=com
instanceType: 4
whenCreated: 20190408054717.0Z
whenChanged: 20220329124205.0Z
uSNCreated: 157601882
uSNChanged: 984032823
name: stargate_self_service_admin
sAMAccountName: stargate_self_service_admin
sAMAccountType: 268435456
groupType: -2147483646
objectCategory: CN=Group,CN=Schema,CN=Configuration,DC=ds,DC=company,DC=com
dSCorePropagationData: 20220323071410.0Z

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

Wonder if there is compatibility I could work with here by isolating my group search to a singular group I want members to be a part of without having to change your code impl...

@jeremyjpj0916
Copy link
Contributor

jeremyjpj0916 commented Apr 15, 2022

If anyone else uses MS AD LDAP and needs guidance I found a pattern that works for me so throwing it here incase it helps any weary traveler, caveat being it limits you to 1 group to do admin access control but it works!

KONGA_LDAP_USER_SEARCH_BASE: CN=Users,dc=ms,dc=ds,dc=COMPANY,dc=com
KONGA_LDAP_GROUP_SEARCH_BASE: CN=YOUR_GROUP_HERE,CN=Users,dc=ms,dc=ds,dc=COMPANY,dc=com
KONGA_LDAP_GROUP_SEARCH_FILTER: (member=CN={{uid}},CN=Users,DC=ms,DC=ds,DC=COMPANY,DC=com)
KONGA_LDAP_GROUP_ATTRS: cn,member
KONGA_ADMIN_GROUP_REG: ^.*$

What I think it does is: 1 user search makes sure valid user.

  1. Group search our groups uid being my MS username are under the same Users CN but also adding a extra CN=your_group_here etc paired with the (member=CN={{uid}},CN=Users,DC=ms,DC=ds,DC=COMPANY,DC=com) will only RETURN data if that user has that YOUR_GROUP_HERE membership.

Then the REGEX is just a match all, meaning if we got proper data of any kind back then user met the criteria, its not pretty but did work for me and distinguish regular users from admin users via a MS AD LDAP group. Phew this took awhile to crack but found a hacky way to make it work for me.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants