Skip to content

Commit

Permalink
fix: use plugin.get to fetch plugin configured in multi-auth plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
Revolyssup committed Nov 29, 2024
1 parent a7524c0 commit 8d29045
Show file tree
Hide file tree
Showing 3 changed files with 292 additions and 2 deletions.
5 changes: 3 additions & 2 deletions apisix/plugins/multi-auth.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ local core = require("apisix.core")
local require = require
local pairs = pairs
local type = type
local plugin = require("apisix.plugin")

local schema = {
type = "object",
Expand Down Expand Up @@ -48,7 +49,7 @@ function _M.check_schema(conf)
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)
local auth = plugin.get(auth_plugin_name)
if auth == nil then
return false, auth_plugin_name .. " plugin did not found"
else
Expand All @@ -73,7 +74,7 @@ function _M.rewrite(conf, ctx)

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)
local auth = plugin.get(auth_plugin_name)
-- returns 401 HTTP status code if authentication failed, otherwise returns nothing.
local auth_code, err = auth.rewrite(auth_plugin_conf, ctx)
if type(err) == "table" then
Expand Down
94 changes: 94 additions & 0 deletions t/assets/custom-auth-plugin.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
local core = require("apisix.core")
local consumer_mod = require("apisix.consumer")
local plugin_name = "custom-key-auth"


local schema = {
type = "object",
properties = {
header = {
type = "string",
default = "apikey",
},
query = {
type = "string",
default = "apikey",
},
hide_credentials = {
type = "boolean",
default = false,
}
},
}

local consumer_schema = {
type = "object",
properties = {
key = { type = "string" },
},
encrypt_fields = {"key"},
required = {"key"},
}


local _M = {
version = 0.1,
priority = 2500,
type = "auth",
name = plugin_name,
schema = schema,
consumer_schema = consumer_schema,
}


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


function _M.rewrite(conf, ctx)
local from_header = true
local key = core.request.header(ctx, conf.header)

if not key then
local uri_args = core.request.get_uri_args(ctx) or {}
key = uri_args[conf.query]
from_header = false
end

if not key then
return 401, {message = "Missing API key found in request"}
end

local consumer_conf = consumer_mod.plugin(plugin_name)
if not consumer_conf then
return 401, {message = "Missing related consumer"}
end

local consumers = consumer_mod.consumers_kv(plugin_name, consumer_conf, "key")
local consumer = consumers[key]
if not consumer then
return 401, {message = "Invalid API key in request"}
end
core.log.info("consumer: ", core.json.delay_encode(consumer))

if conf.hide_credentials then
if from_header then
core.request.set_header(ctx, conf.header, nil)
else
local args = core.request.get_uri_args(ctx)
args[conf.query] = nil
core.request.set_uri_args(ctx, args)
end
end

consumer_mod.attach_consumer(ctx, consumer, consumer_conf)
core.log.info("hit custom-key-auth rewrite")
end


return _M
195 changes: 195 additions & 0 deletions t/plugin/multi-auth-custom-plugin.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
use t::APISIX 'no_plan';

repeat_each(1);
no_long_string();
no_root_location();
no_shuffle();
log_level("info");


add_block_preprocessor(sub {
my ($block) = @_;

my $extra_init_by_lua_start = <<_EOC_;
require "agent.hook";
_EOC_

if (!defined $block->extra_init_by_lua_start) {
$block->set_value("extra_init_by_lua_start", $extra_init_by_lua_start);
}

my $http_config = $block->http_config // <<_EOC_;
lua_shared_dict config 5m;
_EOC_
$block->set_value("http_config", $http_config);

my $extra_init_by_lua = <<_EOC_;
local server = require("lib.server")
server.api_dataplane_heartbeat = function()
ngx.say("{}")
end
server.api_dataplane_metrics = function()
end
server.apisix_prometheus_metrics = function()
ngx.say('apisix_http_status{code="200",route="httpbin",matched_uri="/*",matched_host="nic.httpbin.org",service="",consumer="",node="172.30.5.135"} 61')
end
_EOC_

$block->set_value("extra_init_by_lua", $extra_init_by_lua);

my $extra_yaml_config = $block->extra_yaml_config // <<_EOC_;
plugin_attr:
prometheus:
export_addr:
port: 1980
_EOC_

$block->set_value("extra_yaml_config", $extra_yaml_config);

if ((!defined $block->error_log) && (!defined $block->no_error_log)) {
$block->set_value("no_error_log", "[error]\n[alert]");
}
});
run_tests;

__DATA__
=== TEST 1: API7EE custom auth plugin in multi-auth plugin should work
--- extra_init_by_lua_start
--- extra_yaml_config
apisix:
lua_module_hook: ""
--- config
location /t {
content_by_lua_block {
local core = require("apisix.core")
local t = require("lib.test_admin").test
local util = require("apisix.cli.util")
local custom_plugin = util.read_file("t/assets/custom-auth-plugin.lua")
local key = "/custom_plugins/custom-key-auth"
local val = {
name = "custom-key-auth",
content = custom_plugin
}
local _, err = core.etcd.set(key, val)
if err then
ngx.say(err)
return
end
local code, body = t('/apisix/admin/consumers',
ngx.HTTP_PUT,
[[{
"username": "foo",
"plugins": {
"basic-auth": {
"username": "foo",
"password": "bar"
},
"custom-key-auth": {
"key": "auth-one"
}
}
}]]
)
if code >= 300 then
ngx.status = code
return
end
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"plugins": {
"multi-auth": {
"auth_plugins": [
{
"basic-auth": {}
},
{
"custom-key-auth": {
"hide_credentials": true
}
},
{
"jwt-auth": {
"hide_credentials": true
}
}
]
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/hello"
}]]
)
if code >= 300 then
ngx.status = code
return
end
-- verify custom-key-auth
-- verify correct APIKEY
local code, body = t("/hello", ngx.HTTP_GET, nil, nil, {
apikey = "auth-one"
})
if code >= 300 then
ngx.status = code
return
end
-- verify incorrect APIKEY
local code, body = t("/hello", ngx.HTTP_GET, nil, nil, {
apikey = "not-auth-one"
})
if code ~= 401 then
ngx.status = 503
return
end
--------------------------------------------
-- verify basic-auth
-- verify correct Authorization header
local code, body = t("/hello", ngx.HTTP_GET, nil, nil, {
Authorization = "Basic Zm9vOmJhcg=="
})
if code >= 300 then
ngx.status = code
return
end
-- verify incorrect Authorization header
local code, body = t("/hello", ngx.HTTP_GET, nil, nil, {
Authorization = "Basic wrong-token"
})
if code ~= 401 then
ngx.status = 503
return
end
ngx.say("done")
}
}
--- request
GET /t
--- response_body
done

0 comments on commit 8d29045

Please sign in to comment.