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
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
a5d1ab9
add lualdap
jp-gouin Mar 16, 2021
2e2ffb0
add ldap plugin
jp-gouin Mar 16, 2021
6cfe4cd
add ldap plugin
jp-gouin Mar 16, 2021
7b01646
add ldap plugin
jp-gouin Mar 16, 2021
979e46b
add ldap-auth plugin , add test case , need to debug the test case
jp-gouin Mar 23, 2021
d46d980
correct typo
jp-gouin Mar 23, 2021
fad0827
update of readme and test case
jp-gouin Mar 23, 2021
d410f56
add test cases for ldap-auth plugin, update travis to deploy openldap…
jp-gouin Apr 6, 2021
8a43bc3
resolve merge conflict
jp-gouin Apr 6, 2021
6c29529
resolve merge conflict
jp-gouin Apr 6, 2021
3946036
remove trailing space, use libldap libldap-2.4-2
jp-gouin Apr 6, 2021
b67b69d
change libldap to libldap2-dev to avoid error upon lualdap installation
jp-gouin Apr 6, 2021
47d30e1
resolve merge conflicts
jp-gouin Aug 21, 2021
0bbc7e4
Merge branch 'apache-master' into master
jp-gouin Aug 21, 2021
c178e17
Add dependency openldap-devel or libldap2-dev for CI.
jp-gouin Aug 22, 2021
bb2ccfd
mispelling in ldap-auth
jp-gouin Aug 22, 2021
cb8cb6f
remove unused variable
jp-gouin Aug 22, 2021
48870cb
add libldap2-dev in Linux Get dependencies step
jp-gouin Aug 22, 2021
a2ceb94
update admin/plugins test cases 1 and 9 to include ldap-auth
jp-gouin Sep 14, 2021
7d10e1e
patch error when linking label to versionDB , the new api of harbor i…
jp-gouin Sep 14, 2021
558f8a8
update admin/plugins test cases 1 to include ldap-auth at the right p…
jp-gouin Sep 14, 2021
66b69a7
Merge branch 'master' of github.com:jp-gouin/apisix into master
jp-gouin Sep 14, 2021
078f628
change require style to match existing requirs , remove additionalPro…
jp-gouin Sep 18, 2021
23253f4
change require style to match existing requirs , remove additionalPro…
jp-gouin Sep 18, 2021
33fc909
remove additionalProperties from test case
jp-gouin Sep 19, 2021
89f8d6a
Add openldap reference in the install-dependencies.md, add sub foncti…
jp-gouin Oct 2, 2021
15cf6ee
resolve merge conflict
jp-gouin Oct 2, 2021
9c87c10
remove trailing space, reindex test case
jp-gouin Oct 2, 2021
9663476
add verification on extract_header, remove reference to apisix dashbo…
jp-gouin Oct 4, 2021
abe1090
revert wrong commit, add check on extract_header
jp-gouin Oct 4, 2021
10a4d87
remove unnecessary check
jp-gouin Oct 4, 2021
8ab4df8
commit change per review
jp-gouin Oct 10, 2021
79b01a6
add libldap2-dev dependency in .github/workflows/cli.yml
jp-gouin Oct 10, 2021
78032ba
remove unexisting err from ngx.decode_base64(m[1])
jp-gouin Oct 11, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,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.


- name: Linux Before install
run: sudo ./ci/${{ matrix.os_name }}_runner.sh before_install
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ jobs:
key: ${{ runner.os }}-${{ env.cache-name }}-${{ matrix.job_name }}-${{ hashFiles('rockspec/apisix-master-0.rockspec') }}

- 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
jp-gouin marked this conversation as resolved.
Show resolved Hide resolved

- name: Linux Before install
run: sudo ./ci/${{ matrix.job_name }}_runner.sh before_install
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/fuzzing-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ jobs:
sudo apt-get -y install software-properties-common
sudo add-apt-repository -y "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main"
sudo apt-get update
sudo apt-get install -y git openresty curl openresty-openssl111-dev unzip make gcc
sudo apt-get install -y git openresty curl openresty-openssl111-dev unzip make gcc libldap2-dev
./utils/linux-install-luarocks.sh

make deps
Expand Down
160 changes: 160 additions & 0 deletions apisix/plugins/ldap-auth.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one or more
-- contributor license agreements. See the NOTICE file distributed with
-- this work for additional information regarding copyright ownership.
-- The ASF licenses this file to You under the Apache License, Version 2.0
-- (the "License"); you may not use this file except in compliance with
-- the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
local core = require("apisix.core")
local ngx = ngx
local ngx_re = require("ngx.re")
local ipairs = ipairs
local consumer_mod = require("apisix.consumer")
local lualdap = require("lualdap")

local lrucache = core.lrucache.new({
ttl = 300, count = 512
})

local schema = {
type = "object",
title = "work with route or service object",
properties = {
base_dn = { type = "string" },
ldap_uri = { type = "string" },
use_tls = { type = "boolean" },
uid = { type = "string" }
},
required = {"base_dn","ldap_uri"},
}

local consumer_schema = {
type = "object",
title = "work with consumer object",
properties = {
user_dn = { type = "string" },
},
required = {"user_dn"},
}

local plugin_name = "ldap-auth"

local _M = {
version = 0.1,
priority = 2540,
type = 'auth',
name = plugin_name,
schema = schema,
consumer_schema = consumer_schema
}

function _M.check_schema(conf, schema_type)
local ok, err
if schema_type == core.schema.TYPE_CONSUMER then
ok, err = core.schema.check(consumer_schema, conf)
else
ok, err = core.schema.check(schema, conf)
end

return ok, err
end

local create_consumer_cache
do
local consumer_names = {}

function create_consumer_cache(consumers)
core.table.clear(consumer_names)

for _, consumer in ipairs(consumers.nodes) do
core.log.info("consumer node: ", core.json.delay_encode(consumer))
consumer_names[consumer.auth_conf.user_dn] = consumer
Copy link
Contributor

Choose a reason for hiding this comment

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

What if two users use the same user_dn?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A distinguish name (dn) is per definition unique so user cannot share the same dn

Copy link
Contributor

Choose a reason for hiding this comment

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

Got it.

Copy link
Contributor

Choose a reason for hiding this comment

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

But what if the admin configured the same dn for different consumers accidentally? Is it harmless or there are some side effects?

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 it's harmeless, is there a way in the consumer definition to identify a unique field ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Got it.

is there a way in the consumer definition to identify a unique field

We have to check it by our own. It seems that the JSON schema cannot help us to do it. Anyway, we may document it.

end

return consumer_names
end

end -- do

local function extract_auth_header(authorization)
local obj = { username = "", password = "" }

local m, err = ngx.re.match(authorization, "Basic\\s(.+)", "jo")
if err then
-- error authorization
return nil, err
end

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

if not decoded then
return nil, "failed to decode authentication header: " .. m[1]
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


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.

if err then
return nil, "split authorization err:" .. err
end
if #res < 2 then
return nil, "split authorization err: invalid decoded data: " .. decoded
end

obj.username = ngx.re.gsub(res[1], "\\s+", "", "jo")
obj.password = ngx.re.gsub(res[2], "\\s+", "", "jo")

return obj, nil
end

function _M.rewrite(conf, ctx)
core.log.info("plugin rewrite phase, conf: ", core.json.delay_encode(conf))

-- 1. extract authorization from header
local auth_header = core.request.header(ctx, "Authorization")
if not auth_header then
core.response.set_header("WWW-Authenticate", "Basic realm='.'")
return 401, { message = "Missing authorization in request" }
end

local user, err = extract_auth_header(auth_header)
if err then
return 401, { message = err }
end

-- 2. try authenticate the user against the ldap server
local uid = "cn"
if conf.uid then
uid = conf.uid
end
local userdn = uid .. "=" .. user.username .. "," .. conf.base_dn
local ld = lualdap.open_simple (conf.ldap_uri, userdn, user.password, conf.use_tls)
if not ld then
return 401, { message = "Invalid user authorization" }
end

-- 3. Retrieve consumer for authorization plugin
local consumer_conf = consumer_mod.plugin(plugin_name)
if not consumer_conf then
return 401, {message = "Missing related consumer"}
end
local consumers = lrucache("consumers_key", consumer_conf.conf_version,
create_consumer_cache, consumer_conf)
local consumer = consumers[userdn]
if not consumer then
return 401, {message = "Invalid API key in request"}
end
consumer_mod.attach_consumer(ctx, consumer, consumer_conf)

core.log.info("hit basic-auth access")
end

return _M
2 changes: 1 addition & 1 deletion ci/centos7-ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ install_dependencies() {

# install development tools
yum install -y wget tar gcc automake autoconf libtool make unzip \
curl git which sudo
curl git which sudo openldap-devel

# install openresty to make apisix's rpm test work
yum install -y yum-utils && yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
Expand Down
3 changes: 3 additions & 0 deletions ci/install-ext-services-via-docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ docker run --rm --name skywalking -d -p 1234:1234 -p 11800:11800 -p 12800:12800
docker run --rm --name consul_1 -d -p 8500:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data
docker run --rm --name consul_2 -d -p 8600:8500 consul:1.7 consul agent -server -bootstrap-expect=1 -client 0.0.0.0 -log-level info -data-dir=/consul/data

# start openldap server
docker run -d --rm --name openldap -p 1389:1389 -p 1636:1636 --env LDAP_ADMIN_USERNAME=admin --env LDAP_ADMIN_PASSWORD=adminpassword --env LDAP_USERS=user01,user02 --env LDAP_PASSWORDS=password1,password2 bitnami/openldap:latest

# start nacos server
docker network rm nacos_net
docker network create nacos_net
Expand Down
1 change: 1 addition & 0 deletions conf/config-default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ plugins: # plugin list (sorted by priority)
- openid-connect # priority: 2599
- authz-casbin # priority: 2560
- wolf-rbac # priority: 2555
- ldap-auth # priority: 2540
- hmac-auth # priority: 2530
- basic-auth # priority: 2520
- jwt-auth # priority: 2510
Expand Down
3 changes: 2 additions & 1 deletion docs/en/latest/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@
"plugins/wolf-rbac",
"plugins/openid-connect",
"plugins/hmac-auth",
"plugins/authz-casbin"
"plugins/authz-casbin",
"plugins/ldap-auth"
]
},
{
Expand Down
10 changes: 5 additions & 5 deletions docs/en/latest/install-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ sudo yum install yum-utils
sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo

# install OpenResty and some compilation tools
sudo yum install -y openresty curl git gcc openresty-openssl111-devel unzip pcre pcre-devel
sudo yum install -y openresty curl git gcc openresty-openssl111-devel unzip pcre pcre-devel libldap2-dev

# install LuaRocks
curl https://raw.githubusercontent.com/apache/apisix/master/utils/linux-install-luarocks.sh -sL | bash -
Expand All @@ -81,7 +81,7 @@ tar -xvf etcd-v3.4.13-linux-amd64.tar.gz && \
sudo cp -a etcd etcdctl /usr/bin/

# install OpenResty and some compilation tools
sudo yum install -y openresty curl git gcc openresty-openssl111-devel pcre pcre-devel
sudo yum install -y openresty curl git gcc openresty-openssl111-devel pcre pcre-devel libldap2-dev

# install LuaRocks
curl https://raw.githubusercontent.com/apache/apisix/master/utils/linux-install-luarocks.sh -sL | bash -
Expand All @@ -107,7 +107,7 @@ tar -xvf etcd-v3.4.13-linux-amd64.tar.gz && \
sudo cp -a etcd etcdctl /usr/bin/

# install OpenResty and some compilation tools
sudo apt-get install -y git openresty curl openresty-openssl111-dev make gcc libpcre3 libpcre3-dev
sudo apt-get install -y git openresty curl openresty-openssl111-dev make gcc libpcre3 libpcre3-dev libldap2-dev

# install LuaRocks
curl https://raw.githubusercontent.com/apache/apisix/master/utils/linux-install-luarocks.sh -sL | bash -
Expand Down Expand Up @@ -138,7 +138,7 @@ tar -xvf etcd-v3.4.13-linux-amd64.tar.gz && \
sudo cp -a etcd etcdctl /usr/bin/

# install OpenResty and some compilation tools
sudo apt-get install -y git openresty curl make openresty-openssl111-dev libpcre3 libpcre3-dev
sudo apt-get install -y git openresty curl make openresty-openssl111-dev libpcre3 libpcre3-dev libldap2-dev

# install LuaRocks
curl https://raw.githubusercontent.com/apache/apisix/master/utils/linux-install-luarocks.sh -sL | bash -
Expand All @@ -151,7 +151,7 @@ nohup etcd &

```shell
# install OpenResty, etcd and some compilation tools
brew install openresty/brew/openresty luarocks lua@5.1 etcd curl git pcre
brew install openresty/brew/openresty luarocks lua@5.1 etcd curl git pcre openldap

# start etcd server
brew services start etcd
Expand Down
Loading