Skip to content

Commit

Permalink
add hide_credentials option for multi-auth plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
Madhawa Gunasekara authored and Madhawa Gunasekara committed Apr 15, 2024
1 parent 1dfce2b commit 7460aef
Show file tree
Hide file tree
Showing 5 changed files with 255 additions and 37 deletions.
33 changes: 2 additions & 31 deletions apisix/plugins/jwt-auth.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,14 @@
local core = require("apisix.core")
local jwt = require("resty.jwt")
local consumer_mod = require("apisix.consumer")
local plugin_util = require("apisix.utils.plugin-util")
local resty_random = require("resty.random")
local new_tab = require ("table.new")

local ngx_encode_base64 = ngx.encode_base64
local ngx_decode_base64 = ngx.decode_base64
local ngx = ngx
local ngx_time = ngx.time
local sub_str = string.sub
local table_insert = table.insert
local table_concat = table.concat
local ngx_re_gmatch = ngx.re.gmatch
local plugin_name = "jwt-auth"
local pcall = pcall

Expand Down Expand Up @@ -151,32 +148,6 @@ function _M.check_schema(conf, schema_type)
return true
end

local function remove_specified_cookie(src, key)
local cookie_key_pattern = "([a-zA-Z0-9-_]*)"
local cookie_val_pattern = "([a-zA-Z0-9-._]*)"
local t = new_tab(1, 0)

local it, err = ngx_re_gmatch(src, cookie_key_pattern .. "=" .. cookie_val_pattern, "jo")
if not it then
core.log.error("match origins failed: ", err)
return src
end
while true do
local m, err = it()
if err then
core.log.error("iterate origins failed: ", err)
return src
end
if not m then
break
end
if m[1] ~= key then
table_insert(t, m[0])
end
end

return table_concat(t, "; ")
end

local function fetch_jwt_token(conf, ctx)
local token = core.request.header(ctx, conf.header)
Expand Down Expand Up @@ -213,7 +184,7 @@ local function fetch_jwt_token(conf, ctx)
if conf.hide_credentials then
-- hide for cookie
local src = core.request.header(ctx, "Cookie")
local reset_val = remove_specified_cookie(src, conf.cookie)
local reset_val = plugin_util.remove_specified_cookie(src, conf.cookie)
core.request.set_header(ctx, "Cookie", reset_val)
end

Expand Down
49 changes: 43 additions & 6 deletions apisix/plugins/multi-auth.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,19 @@
-- limitations under the License.
--
local core = require("apisix.core")
local plugin_util = require("apisix.utils.plugin-util")
local require = require
local pairs = pairs

local schema = {
type = "object",
title = "work with route or service object",
properties = {
auth_plugins = { type = "array", minItems = 2 }
auth_plugins = { type = "array", minItems = 2 },
hide_credentials = {
type = "boolean",
default = false
}
},
required = { "auth_plugins" },
}
Expand Down Expand Up @@ -72,18 +77,50 @@ function _M.rewrite(conf, ctx)
status_code = auth_code
if auth_code == nil then
core.log.debug(auth_plugin_name .. " succeed to authenticate the request")
goto authenticated
goto hide_credentials
else
core.log.debug(auth_plugin_name .. " failed to authenticate the request, code: "
.. auth_code)
end
end
end
goto hide_credentials


:: hide_credentials ::
if conf.hide_credentials then
for k, auth_plugin in pairs(auth_plugins) do
for auth_plugin_name, auth_plugin_conf in pairs(auth_plugin) do
-- hide for header
if auth_plugin_conf.header ~= nil then
core.request.set_header(ctx, auth_plugin_conf.header, nil)
end
-- hide for query
if auth_plugin_conf.query ~= nil then
local uri_args = core.request.get_uri_args(ctx) or {}
local token = uri_args[conf.query]
if token then
uri_args[auth_plugin_conf.query] = nil
core.request.set_uri_args(ctx, uri_args)

end

end
-- hide for cookie
if auth_plugin_conf.cookie ~= nil then
local src = core.request.header(ctx, "Cookie")
local reset_val = plugin_util.remove_specified_cookie(src,
auth_plugin_conf.cookie)
core.request.set_header(ctx, "Cookie", reset_val)

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

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

return _M
58 changes: 58 additions & 0 deletions apisix/utils/plugin-util.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
--
-- 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 new_tab = require ("table.new")

local ngx = ngx
local table_insert = table.insert
local table_concat = table.concat
local ngx_re_gmatch = ngx.re.gmatch


local _M = {}




function _M.remove_specified_cookie(src, key)
local cookie_key_pattern = "([a-zA-Z0-9-_]*)"
local cookie_val_pattern = "([a-zA-Z0-9-._]*)"
local t = new_tab(1, 0)

local it, err = ngx_re_gmatch(src, cookie_key_pattern .. "=" .. cookie_val_pattern, "jo")
if not it then
core.log.error("match origins failed: ", err)
return src
end
while true do
local m, err = it()
if err then
core.log.error("iterate origins failed: ", err)
return src
end
if not m then
break
end
if m[1] ~= key then
table_insert(t, m[0])
end
end

return table_concat(t, "; ")
end

return _M
1 change: 1 addition & 0 deletions docs/en/latest/plugins/multi-auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ For Route:
| Name | Type | Required | Default | Description |
|--------------|-------|----------|---------|-----------------------------------------------------------------------|
| auth_plugins | array | True | - | Add supporting auth plugins configuration. expects at least 2 plugins |
|hide_credentials| boolean| False| false| Set to true will not pass the authorization request of header\query\cookie to the Upstream.|

## Enable Plugin

Expand Down
151 changes: 151 additions & 0 deletions t/plugin/multi-auth.t
Original file line number Diff line number Diff line change
Expand Up @@ -412,3 +412,154 @@ hello world
GET /t
--- response_body
hello world



=== TEST 14: enable multi auth plugin with same header without hide credential
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"plugins": {
"multi-auth": {
"auth_plugins": [
{
"basic-auth": {}
},
{
"key-auth": {
"query": "apikey",
"header": "authorization"
}
},
{
"jwt-auth": {
"cookie": "jwt",
"query": "jwt",
"header": "authorization"
}
}
]
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/hello"
}]]
)

if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed



=== TEST 15: verify key-auth with same header
--- request
GET /hello
--- more_headers
Authorization: auth-one
--- response_body
hello world



=== TEST 16: verify multi auth plugin (in header) with hiding credentials
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"plugins": {
"multi-auth": {
"auth_plugins": [
{
"basic-auth": {}
},
{
"key-auth": {
"query": "apikey",
"header": "authorization"
}
},
{
"jwt-auth": {
"cookie": "jwt",
"query": "jwt",
"header": "authorization"
}
}
],
"hide_credentials": true
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/hello"
}]]
)

if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /hello
--- more_headers
Authorization: auth-one
--- response_headers
!Authorization



=== TEST 17: verify jwt-auth with same header
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, err, sign = t('/apisix/plugin/jwt/sign?key=user-key',
ngx.HTTP_GET
)

if code > 200 then
ngx.status = code
ngx.say(err)
return
end

-- verify JWT token
local http = require("resty.http")
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello"
local httpc = http.new()
local res, err = httpc:request_uri(uri, {headers={authorization=sign}})

ngx.status = res.status
ngx.print(res.body)
}
}
--- request
GET /t
--- response_body
hello world

0 comments on commit 7460aef

Please sign in to comment.