Skip to content

Commit

Permalink
feat: add multi-auth plugin (#10482)
Browse files Browse the repository at this point in the history
Co-authored-by: Madhawa Gunasekara <Madhawa.Gunasekara@trelleborg.com>
  • Loading branch information
madhawa-gunasekara and Madhawa Gunasekara authored Nov 20, 2023
1 parent ec77fb8 commit 5b7b1de
Show file tree
Hide file tree
Showing 9 changed files with 655 additions and 2 deletions.
89 changes: 89 additions & 0 deletions apisix/plugins/multi-auth.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
--
-- 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 require = require
local pairs = pairs

local schema = {
type = "object",
title = "work with route or service object",
properties = {
auth_plugins = { type = "array", minItems = 2 }
},
required = { "auth_plugins" },
}


local plugin_name = "multi-auth"

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

function _M.check_schema(conf)
local ok, err = core.schema.check(schema, conf)
if not ok then
return false, err
end

local auth_plugins = conf.auth_plugins
for k, auth_plugin in pairs(auth_plugins) do
for auth_plugin_name, auth_plugin_conf in pairs(auth_plugin) do
local auth = require("apisix.plugins." .. auth_plugin_name)
if auth == nil then
return false, auth_plugin_name .. " plugin did not found"
else
if auth.type ~= 'auth' then
return false, auth_plugin_name .. " plugin is not supported"
end
end
end
end

return true
end

function _M.rewrite(conf, ctx)
local auth_plugins = conf.auth_plugins
local status_code
for k, auth_plugin in pairs(auth_plugins) do
for auth_plugin_name, auth_plugin_conf in pairs(auth_plugin) do
local auth = require("apisix.plugins." .. auth_plugin_name)
-- returns 401 HTTP status code if authentication failed, otherwise returns nothing.
local auth_code = auth.rewrite(auth_plugin_conf, ctx)
status_code = auth_code
if auth_code == nil then
core.log.debug(auth_plugin_name .. " succeed to authenticate the request")
goto authenticated
else
core.log.debug(auth_plugin_name .. " failed to authenticate the request, code: "
.. auth_code)
end
end
end

:: authenticated ::
if status_code ~= nil then
return 401, { message = "Authorization Failed" }
end
end

return _M
1 change: 1 addition & 0 deletions conf/config-default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ plugins: # plugin list (sorted by priority)
- uri-blocker # priority: 2900
- request-validation # priority: 2800
- chaitin-waf # priority: 2700
- multi-auth # priority: 2600
- openid-connect # priority: 2599
- cas-auth # priority: 2597
- authz-casbin # priority: 2560
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 @@ -111,7 +111,8 @@
"plugins/authz-casbin",
"plugins/ldap-auth",
"plugins/opa",
"plugins/forward-auth"
"plugins/forward-auth",
"plugins/multi-auth"
]
},
{
Expand Down
1 change: 1 addition & 0 deletions docs/en/latest/getting-started/key-authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ APISIX has a flexible plugin extension system and a number of existing plugins f
- [LDAP](https://apisix.apache.org/docs/apisix/plugins/ldap-auth/)
- [Open Policy Agent (OPA)](https://apisix.apache.org/docs/apisix/plugins/opa/)
- [Forward Authentication](https://apisix.apache.org/docs/apisix/plugins/forward-auth/)
- [Multiple Authentications](https://apisix.apache.org/docs/apisix/plugins/multi-auth/)

In this tutorial, you will create a _consumer_ with _key authentication_, and learn how to enable and disable key authentication.

Expand Down
144 changes: 144 additions & 0 deletions docs/en/latest/plugins/multi-auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
---
title: multi-auth
keywords:
- Apache APISIX
- API Gateway
- Plugin
- Multi Auth
- multi-auth
description: This document contains information about the Apache APISIX multi-auth Plugin.
---

<!--
#
# 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.
#
-->

## Description

The `multi-auth` Plugin is used to add multiple authentication methods to a Route or a Service. It supports plugins of type 'auth'. You can combine different authentication methods using "or" relationship with `multi-auth` plugin. If you want to use multiple methods in an "and" relationship, apply specific authentication plugins directly to the route or service.

## Attributes

For Route:

| Name | Type | Required | Default | Description |
|--------------|-------|----------|---------|-----------------------------------------------------------------------|
| auth_plugins | array | True | - | Add supporting auth plugins configuration. expects at least 2 plugins |

## Enable Plugin

To enable the Plugin, you have to create a Consumer object with multiple authentication configurations:

```shell
curl http://127.0.0.1:9180/apisix/admin/consumers -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"username": "foo",
"plugins": {
"basic-auth": {
"username": "foo",
"password": "bar"
},
"key-auth": {
"key": "auth-one"
}
}
}'
```

You can also use the [APISIX Dashboard](/docs/dashboard/USER_GUIDE) to complete the operation through a web UI.

Once you have created a Consumer object, you can then configure a Route or a Service to authenticate requests:

```shell
curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"methods": ["GET"],
"uri": "/hello",
"plugins": {
"multi-auth":{
"auth_plugins":[
{
"basic-auth":{ }
},
{
"key-auth":{
"query":"apikey",
"hide_credentials":true,
"header":"apikey"
}
}
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'
```

## Example usage

After you have configured the Plugin as mentioned above, you can make a request to the Route as shown below:

request with basic-auth

```shell
curl -i -ufoo:bar http://127.0.0.1:9080/hello
```

request with key-auth

```shell
curl http://127.0.0.2:9080/hello -H 'apikey: auth-one' -i
```

```
HTTP/1.1 200 OK
...
hello, world
```

If the request is not authorized, an error will be thrown:

```shell
HTTP/1.1 401 Unauthorized
...
{"message":"Authorization Failed"}
```

## Delete Plugin

To remove the `multi-auth` Plugin, you can delete the corresponding JSON configuration from the Plugin configuration. APISIX will automatically reload and you do not have to restart for this to take effect.

```shell
curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"methods": ["GET"],
"uri": "/hello",
"plugins": {},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'
```
1 change: 1 addition & 0 deletions docs/zh/latest/getting-started/key-authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ APISIX 拥有灵活的插件扩展系统,目前有很多可用于用户身份
- [LDAP](https://apisix.apache.org/zh/docs/apisix/plugins/ldap-auth/)
- [Open Policy Agent (OPA)](https://apisix.apache.org/zh/docs/apisix/plugins/opa/)
- [Forward Authentication](https://apisix.apache.org/zh/docs/apisix/plugins/forward-auth/)
- [Multiple Authentications](https://apisix.apache.org/docs/apisix/plugins/multi-auth/)

本教程中,你将创建一个带有 _密钥验证_ 插件的 _消费者_,并学习如何启用和停用身份验证插件。

Expand Down
3 changes: 2 additions & 1 deletion t/admin/plugins.t
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ csrf
uri-blocker
request-validation
chaitin-waf
multi-auth
openid-connect
cas-auth
authz-casbin
Expand Down Expand Up @@ -311,7 +312,7 @@ qr/\{"metadata_schema":\{"properties":\{"ikey":\{"minimum":0,"type":"number"\},"
}
}
--- response_body eval
qr/\[\{"name":"wolf-rbac","priority":2555\},\{"name":"ldap-auth","priority":2540\},\{"name":"hmac-auth","priority":2530\},\{"name":"basic-auth","priority":2520\},\{"name":"jwt-auth","priority":2510\},\{"name":"key-auth","priority":2500\}\]/
qr/\[\{"name":"multi-auth","priority":2600\},\{"name":"wolf-rbac","priority":2555\},\{"name":"ldap-auth","priority":2540\},\{"name":"hmac-auth","priority":2530\},\{"name":"basic-auth","priority":2520\},\{"name":"jwt-auth","priority":2510\},\{"name":"key-auth","priority":2500\}\]/
Expand Down
1 change: 1 addition & 0 deletions t/debug/debug-mode.t
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ loaded plugin and sort by priority: 3000 name: ip-restriction
loaded plugin and sort by priority: 2990 name: referer-restriction
loaded plugin and sort by priority: 2900 name: uri-blocker
loaded plugin and sort by priority: 2800 name: request-validation
loaded plugin and sort by priority: 2600 name: multi-auth
loaded plugin and sort by priority: 2599 name: openid-connect
loaded plugin and sort by priority: 2555 name: wolf-rbac
loaded plugin and sort by priority: 2530 name: hmac-auth
Expand Down
Loading

0 comments on commit 5b7b1de

Please sign in to comment.