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

feat: Add ldap-auth plugin #3894

Merged
merged 34 commits into from
Oct 13, 2021
Merged

feat: Add ldap-auth plugin #3894

merged 34 commits into from
Oct 13, 2021

Conversation

jp-gouin
Copy link
Contributor

What this PR does / why we need it:

This PR add a new authentication plugin that use a LDAP server to authenticate the user

This add a new type of consumer

"ldap-auth": {
    "userdn": "cn=user01,dc=example,dc=org"
 }

This plugin can also automatically create a consumer upon request if auto_create_consumer = true
This fixes : #3861 and #1128

Test cases are not fully operational yet.

Help needed

Also need help to add the deployment of an Openldap server on Github Action.
FYI i used the (bitnami/openldap:2)(https://hub.docker.com/r/bitnami/openldap/) docker image

openldap:
    image: bitnami/openldap:2
    ports:
      - '389:1389'
      - '636:1636'
    environment:
      - LDAP_ADMIN_USERNAME=admin
      - LDAP_ADMIN_PASSWORD=adminpassword
      - LDAP_USERS=user01,user02
      - LDAP_PASSWORDS=password1,password2

Next feature

Add a group variable in the consumer , this group would come from the memberOf (configurable) attribute of the ldap user and add it in the consumer.
Then plugins such as consumer_restriction could be updated to take into account groups -> (which can also be used on basic-auth (and more) plugin where a consumer can also be part of a group)

Pre-submission checklist:

  • Did you explain what problem does this PR solve? Or what new features have been added?
  • [-] Have you added corresponding test cases?
  • Have you modified the corresponding document?
  • Is this PR backward compatible? If it is not backward compatible, please discuss on the mailing list first

@jp-gouin jp-gouin changed the title feat : Add ldap-auth plugin feat: Add ldap-auth plugin Mar 23, 2021

`ldap-auth` is an authentication plugin that can works with `consumer`. Add Ldap Authentication to a `service` or `route`.

The `consumer` then authenticate against the Ldap server using Basic authentication.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"authenticates"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes corrected

ok, err = core.schema.check(schema, conf)
end

if not ok then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return ok, err is enough.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok added

end

-- 3. Retreive consumer for authorization plugin
if conf.auto_create_consumer then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to avoid creating temporary consumers. The temporary consumer may be broken somewhere else.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok remove this feature .
It was more to act like the oidc plugin , that does not require a consumer to be created , but i see your point

| basedn | string | required | | | the base dn of the `ldap` server (example : `ou=users,dc=example,dc=org`) |
| ldapuri | string | required | | | the uri of the ldap server |
| usetls | boolean | optional | `true` | | Boolean flag indicating if Transport Layer Security (TLS) should be used. |
| uid | string | optional | `cn` | | the user's password |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it the password?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No indeed it's the uid attribute that changes depending of the ldap server solution

properties = {
basedn = { type = "string" },
ldapuri = { type = "string" },
usetls = { type = "boolean" },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you use a snake case for the field name, like base_dn / ldap_uri?

Copy link
Contributor Author

@jp-gouin jp-gouin Apr 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok changed

@spacewander
Copy link
Member

@jp-gouin
You can install the docker in:

And the libldap in:

sudo apt-get install "$openresty" lua5.1 liblua5.1-0-dev

@spacewander
Copy link
Member

@membphis @moonming
Can we introduce libldap as an extern dependency? This library needs to be installed manually.

@@ -66,6 +66,7 @@ dependencies = {
"luasec = 0.9-1",
"lua-resty-consul = 0.3-2",
"penlight = 1.9.2-1",
"lualdap = 1.2.3-1",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use the latest release: 1.2.6?

@membphis
Copy link
Member

@membphis @moonming
Can we introduce libldap as an extern dependency? This library needs to be installed manually.

https://github.com/lualdap/lualdap does not declare the license, the author needs to declare the license first, otherwise APISIX cannot use this open-source project.

@jp-gouin
Copy link
Contributor Author

@membphis there is a licence in their website https://lualdap.github.io/lualdap/license
We can open a ticket if the licence needs to be at project level

@spacewander
Copy link
Member

The spirit of the license is that you are free to use LuaLDAP for any purpose at no cost without having to ask us. The only requirement is that if you do use LuaLDAP, then you should give us credit by including the appropriate copyright notice somewhere in your product or its documentation.

IMHO, it seems we can use it after adding the copyright notice.

There is the raw file of the License page: https://github.com/lualdap/lualdap/blob/master/docs/license.md.

@membphis
Copy link
Member

@membphis there is a licence in their website https://lualdap.github.io/lualdap/license
We can open a ticket if the licence needs to be at project level

https://github.com/lualdap/lualdap

there is no information about license: https://github.com/lualdap/lualdap/search?q=license

I created a new issue right now: lualdap/lualdap#21

@jp-gouin
Copy link
Contributor Author

jp-gouin commented Apr 6, 2021

@jp-gouin
You can install the docker in:

And the libldap in:

sudo apt-get install "$openresty" lua5.1 liblua5.1-0-dev

The CI doesn't seems to install libldap2-dev before installing apisix. Am i missing something ?

@spacewander
Copy link
Member

@jp-gouin
Thank you for your contribution.
However, as @membphis mentioned, we need to wait for the author's confirmation in
lualdap/lualdap#21

@spacewander
Copy link
Member

@jp-gouin
You can install the docker in:

And the libldap in:

sudo apt-get install "$openresty" lua5.1 liblua5.1-0-dev

The CI doesn't seems to install libldap2-dev before installing apisix. Am i missing something ?

Some ci cases have their own way to install the library, like:

yum install -y wget tar gcc automake autoconf libtool make unzip \

sudo apt-get install lua5.1 liblua5.1-0-dev

@tzssangglass
Copy link
Member

@jp-gouin hi, are you still interested in continuing this PR?

@jp-gouin
Copy link
Contributor Author

I am , however there is still the licence issue on the lualdap/lualdap#21
As soon has the licence has been validated by @membphis , i will update this PR

@membphis
Copy link
Member

@membphis @moonming
Can we introduce libldap as an extern dependency? This library needs to be installed manually.

@moonming need your help. ^_^

@jp-gouin
Copy link
Contributor Author

jp-gouin commented Aug 18, 2021

@membphis is the information provided in the lualdap/lualdap#21 enough for the use of lualdap in Apisix ?
If so i would be happy to continue working on the PR

@membphis
Copy link
Member

@membphis is the information provided in the lualdap/lualdap#21 enough for the use of lualdap in Apisix ?
If so i would be happy to continue working on the PR

cool, I think you can continue this PR, it fine now.

@membphis
Copy link
Member

I think you need to resolve the conflicting files ^_^




=== TEST 11: invalid schema, not a table
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is another example:

=== TEST 19: schema check

ngx.say("done")
}
}
--- request
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can save "--- request" and "--- no_error_log" in each test by setting a file-level default one.

@@ -89,7 +89,7 @@ jobs:
tar zxvf ${{ steps.branch_env.outputs.fullname }}

- name: Linux Get dependencies
run: sudo apt install -y cpanminus build-essential libncurses5-dev libreadline-dev libssl-dev perl libpcre3 libpcre3-dev
run: sudo apt install -y cpanminus build-essential libncurses5-dev libreadline-dev libssl-dev perl libpcre3 libpcre3-dev libldap2-dev
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jp-gouin
Copy link
Contributor Author

jp-gouin commented Oct 2, 2021

Failed tests do not seems to be related to ldap-auth plugin, do you confirm ?
Chaos test should be ok once PR apache/apisix-docker#222 is merged

local decoded = ngx.decode_base64(m[1])

local res
res, err = ngx_re.split(decoded, ":")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to check if decoded is not nil and the split result has two elements.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually it’s a copy paste from

local decoded = ngx.decode_base64(m[1])
, I’ll try to update the code

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to submit another PR to update basic-auth.

}'
```

you can visit Dashboard `http://127.0.0.1:9080/apisix/dashboard/` and add a Consumer through the web console.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove this part now. The dashboard is not shipped by default.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok will remove , actually it’s a copy paste from

you also can add a Consumer through the web console:

@spacewander
Copy link
Member

Failed tests do not seems to be related to ldap-auth plugin, do you confirm ? Chaos test should be ok once PR apache/apisix-docker#222 is merged

Look like they are just flaky test results.

@membphis
Copy link
Member

membphis commented Oct 7, 2021

@membphis @moonming Can we introduce libldap as an extern dependency? This library needs to be installed manually.

LGTM ^_^

@membphis
Copy link
Member

membphis commented Oct 7, 2021

Needs to install the libldap2-dev in ChaosMesh case.

https://github.com/apache/apisix/pull/3894/checks?check_run_id=3788501510#step:5:1004

Error: Failed installing dependency: https://luarocks.org/lualdap-1.2.6-1.src.rock - Could not find header file for LDAP
  No file ldap.h in /usr/local/include
  No file ldap.h in /usr/include
  No file ldap.h in /include

return nil, "split authorization err:" .. err
end
if #res < 2 then
return nil, "split authorization length is invalid"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return nil, "split authorization length is invalid"
return nil, "split authorization err: invalid decoded data: " .. decoded


if err then
return nil, "failed to decode authentication header"
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if not decoded then
        return nil, "failed to decode authentication header: " .. m[1]
end

@jp-gouin
Copy link
Contributor Author

jp-gouin commented Oct 7, 2021

@membphis , the chaos mesh test is using the apisix-docker project to build apisix :

docker build -t apache/apisix:alpine-local --build-arg APISIX_PATH=. -f Dockerfile .

I submitted a PR to add the library in the apisix-docker apache/apisix-docker#222

@spacewander
Copy link
Member

@jp-gouin
Would you update this PR? It is almost done.

@jp-gouin
Copy link
Contributor Author

@jp-gouin Would you update this PR? It is almost done.

Done :)

@tzssangglass
Copy link
Member

LGTM

@spacewander spacewander merged commit d1c178d into apache:master Oct 13, 2021
@lijing-21
Copy link
Contributor

@jp-gouin,
Hi, Thank you for your contribution! We are excited to hear about your story with APISIX, so we want to invite you to write an article, for reference,you could introduce the reason why you choose to use APISIX, and why you wrote this plugin, or show the readers how to use this plugin. We will publish this article on the official website of Apahce APISIX, I believe it will be of great help to our readers.
Here is my e-mail: lijing959595@gmail.com. Looking forward to your reply!~

@Zeeeeta
Copy link

Zeeeeta commented Jan 11, 2024

Thanks for the effort.
May I know if base_dn only support searching in one level of directory and not searching for the AD objects in subdirectory?

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

Successfully merging this pull request may close these issues.

Proposition ldap-auth plugin
7 participants