Skip to content

Commit a7524c0

Browse files
feat: plugins in multi-auth returns error instead of logging it (#11775)
1 parent 528ec89 commit a7524c0

File tree

6 files changed

+294
-9
lines changed

6 files changed

+294
-9
lines changed

apisix/plugins/basic-auth.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ local core = require("apisix.core")
1818
local ngx = ngx
1919
local ngx_re = require("ngx.re")
2020
local consumer = require("apisix.consumer")
21+
local auth_utils = require("apisix.utils.auth")
22+
2123
local lrucache = core.lrucache.new({
2224
ttl = 300, count = 512
2325
})
@@ -132,6 +134,9 @@ function _M.rewrite(conf, ctx)
132134

133135
local username, password, err = extract_auth_header(auth_header)
134136
if err then
137+
if auth_utils.is_running_under_multi_auth(ctx) then
138+
return 401, err
139+
end
135140
core.log.warn(err)
136141
return 401, { message = "Invalid authorization in request" }
137142
end

apisix/plugins/hmac-auth.lua

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ local ngx_encode_base64 = ngx.encode_base64
2828
local plugin_name = "hmac-auth"
2929
local ALLOWED_ALGORITHMS = {"hmac-sha1", "hmac-sha256", "hmac-sha512"}
3030
local resty_sha256 = require("resty.sha256")
31+
local auth_utils = require("apisix.utils.auth")
3132

3233
local schema = {
3334
type = "object",
@@ -324,16 +325,24 @@ end
324325
function _M.rewrite(conf, ctx)
325326
local params,err = retrieve_hmac_fields(ctx)
326327
if err then
327-
core.log.warn("client request can't be validated: ", err)
328-
return 401, {message = "client request can't be validated: " .. err}
328+
err = "client request can't be validated: " .. err
329+
if auth_utils.is_running_under_multi_auth(ctx) then
330+
return 401, err
331+
end
332+
core.log.warn(err)
333+
return 401, {message = err}
329334
end
330335

331336
if conf.hide_credentials then
332337
core.request.set_header("Authorization", nil)
333338
end
334339
local validated_consumer, err = validate(ctx, conf, params)
335340
if not validated_consumer then
336-
core.log.warn("client request can't be validated: ", err or "Invalid signature")
341+
err = "client request can't be validated: " .. (err or "Invalid signature")
342+
if auth_utils.is_running_under_multi_auth(ctx) then
343+
return 401, err
344+
end
345+
core.log.warn(err)
337346
return 401, {message = "client request can't be validated"}
338347
end
339348

apisix/plugins/jwt-auth.lua

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ local jwt = require("resty.jwt")
1919
local consumer_mod = require("apisix.consumer")
2020
local resty_random = require("resty.random")
2121
local new_tab = require ("table.new")
22+
local auth_utils = require("apisix.utils.auth")
2223

2324
local ngx_encode_base64 = ngx.encode_base64
2425
local ngx_decode_base64 = ngx.decode_base64
@@ -241,7 +242,11 @@ function _M.rewrite(conf, ctx)
241242
local jwt_obj = jwt:load_jwt(jwt_token)
242243
core.log.info("jwt object: ", core.json.delay_encode(jwt_obj))
243244
if not jwt_obj.valid then
244-
core.log.warn("JWT token invalid: ", jwt_obj.reason)
245+
err = "JWT token invalid: " .. jwt_obj.reason
246+
if auth_utils.is_running_under_multi_auth(ctx) then
247+
return 401, err
248+
end
249+
core.log.warn(err)
245250
return 401, {message = "JWT token invalid"}
246251
end
247252

@@ -266,7 +271,11 @@ function _M.rewrite(conf, ctx)
266271

267272
local auth_secret, err = get_auth_secret(consumer.auth_conf)
268273
if not auth_secret then
269-
core.log.error("failed to retrieve secrets, err: ", err)
274+
err = "failed to retrieve secrets, err: " .. err
275+
if auth_utils.is_running_under_multi_auth(ctx) then
276+
return 401, err
277+
end
278+
core.log.error(err)
270279
return 503, {message = "failed to verify jwt"}
271280
end
272281
local claim_specs = jwt:get_default_validation_options(jwt_obj)
@@ -276,7 +285,11 @@ function _M.rewrite(conf, ctx)
276285
core.log.info("jwt object: ", core.json.delay_encode(jwt_obj))
277286

278287
if not jwt_obj.verified then
279-
core.log.warn("failed to verify jwt: ", jwt_obj.reason)
288+
err = "failed to verify jwt: " .. jwt_obj.reason
289+
if auth_utils.is_running_under_multi_auth(ctx) then
290+
return 401, err
291+
end
292+
core.log.warn(err)
280293
return 401, {message = "failed to verify jwt"}
281294
end
282295

apisix/plugins/multi-auth.lua

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
local core = require("apisix.core")
1818
local require = require
1919
local pairs = pairs
20+
local type = type
2021

2122
local schema = {
2223
type = "object",
@@ -68,24 +69,34 @@ end
6869
function _M.rewrite(conf, ctx)
6970
local auth_plugins = conf.auth_plugins
7071
local status_code
72+
local errors = {}
73+
7174
for k, auth_plugin in pairs(auth_plugins) do
7275
for auth_plugin_name, auth_plugin_conf in pairs(auth_plugin) do
7376
local auth = require("apisix.plugins." .. auth_plugin_name)
7477
-- returns 401 HTTP status code if authentication failed, otherwise returns nothing.
75-
local auth_code = auth.rewrite(auth_plugin_conf, ctx)
78+
local auth_code, err = auth.rewrite(auth_plugin_conf, ctx)
79+
if type(err) == "table" then
80+
err = err.message -- compat
81+
end
82+
7683
status_code = auth_code
7784
if auth_code == nil then
7885
core.log.debug(auth_plugin_name .. " succeed to authenticate the request")
7986
goto authenticated
8087
else
81-
core.log.debug(auth_plugin_name .. " failed to authenticate the request, code: "
82-
.. auth_code)
88+
core.table.insert(errors, auth_plugin_name ..
89+
" failed to authenticate the request, code: "
90+
.. auth_code .. ". error: " .. err)
8391
end
8492
end
8593
end
8694

8795
:: authenticated ::
8896
if status_code ~= nil then
97+
for _, error in pairs(errors) do
98+
core.log.warn(error)
99+
end
89100
return 401, { message = "Authorization Failed" }
90101
end
91102
end

apisix/utils/auth.lua

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--
2+
-- Licensed to the Apache Software Foundation (ASF) under one or more
3+
-- contributor license agreements. See the NOTICE file distributed with
4+
-- this work for additional information regarding copyright ownership.
5+
-- The ASF licenses this file to You under the Apache License, Version 2.0
6+
-- (the "License"); you may not use this file except in compliance with
7+
-- the License. You may obtain a copy of the License at
8+
--
9+
-- http://www.apache.org/licenses/LICENSE-2.0
10+
--
11+
-- Unless required by applicable law or agreed to in writing, software
12+
-- distributed under the License is distributed on an "AS IS" BASIS,
13+
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
-- See the License for the specific language governing permissions and
15+
-- limitations under the License.
16+
--
17+
18+
local _M = {}
19+
20+
function _M.is_running_under_multi_auth(ctx)
21+
return ctx._plugin_name == "multi-auth"
22+
end
23+
24+
return _M

t/plugin/multi-auth2.t

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one or more
3+
# contributor license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright ownership.
5+
# The ASF licenses this file to You under the Apache License, Version 2.0
6+
# (the "License"); you may not use this file except in compliance with
7+
# the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
use t::APISIX 'no_plan';
18+
19+
no_long_string();
20+
no_root_location();
21+
no_shuffle();
22+
run_tests;
23+
24+
__DATA__
25+
26+
=== TEST 1: add consumer with basic-auth and key-auth plugins
27+
--- config
28+
location /t {
29+
content_by_lua_block {
30+
local t = require("lib.test_admin").test
31+
local code, body = t('/apisix/admin/consumers',
32+
ngx.HTTP_PUT,
33+
[[{
34+
"username": "foo",
35+
"plugins": {
36+
"basic-auth": {
37+
"username": "foo",
38+
"password": "bar"
39+
},
40+
"jwt-auth": {
41+
"key": "user-key",
42+
"secret": "my-secret-key"
43+
}
44+
}
45+
}]]
46+
)
47+
if code >= 300 then
48+
ngx.status = code
49+
end
50+
ngx.say(body)
51+
}
52+
}
53+
--- request
54+
GET /t
55+
--- response_body
56+
passed
57+
58+
59+
60+
=== TEST 2: enable multi auth plugin using admin api
61+
--- config
62+
location /t {
63+
content_by_lua_block {
64+
local t = require("lib.test_admin").test
65+
local code, body = t('/apisix/admin/routes/1',
66+
ngx.HTTP_PUT,
67+
[[{
68+
"plugins": {
69+
"multi-auth": {
70+
"auth_plugins": [
71+
{
72+
"basic-auth": {}
73+
},
74+
{
75+
"jwt-auth": {}
76+
},
77+
{
78+
"hmac-auth": {}
79+
}
80+
]
81+
}
82+
},
83+
"upstream": {
84+
"nodes": {
85+
"127.0.0.1:1980": 1
86+
},
87+
"type": "roundrobin"
88+
},
89+
"uri": "/hello"
90+
}]]
91+
)
92+
93+
if code >= 300 then
94+
ngx.status = code
95+
end
96+
ngx.say(body)
97+
}
98+
}
99+
--- request
100+
GET /t
101+
--- response_body
102+
passed
103+
104+
105+
106+
=== TEST 3: invalid basic-auth credentials
107+
--- request
108+
GET /hello
109+
--- more_headers
110+
Authorization: Basic YmFyOmJhcgo=
111+
--- error_code: 401
112+
--- response_body
113+
{"message":"Authorization Failed"}
114+
--- error_log
115+
basic-auth failed to authenticate the request, code: 401. error: Invalid user authorization
116+
jwt-auth failed to authenticate the request, code: 401. error: JWT token invalid: invalid jwt string
117+
hmac-auth failed to authenticate the request, code: 401. error: client request can't be validated: Authorization header does not start with 'Signature'
118+
119+
120+
121+
=== TEST 4: valid basic-auth creds
122+
--- request
123+
GET /hello
124+
--- more_headers
125+
Authorization: Basic Zm9vOmJhcg==
126+
--- response_body
127+
hello world
128+
--- no_error_log
129+
failed to authenticate the request
130+
131+
132+
133+
=== TEST 5: missing hmac auth authorization header
134+
--- request
135+
GET /hello
136+
--- error_code: 401
137+
--- response_body
138+
{"message":"Authorization Failed"}
139+
--- error_log
140+
hmac-auth failed to authenticate the request, code: 401. error: client request can't be validated: missing Authorization header
141+
142+
143+
144+
=== TEST 6: hmac auth missing algorithm
145+
--- request
146+
GET /hello
147+
--- more_headers
148+
Authorization: Signature keyId="my-access-key",headers="@request-target date" ,signature="asdf"
149+
Date: Thu, 24 Sep 2020 06:39:52 GMT
150+
--- error_code: 401
151+
--- response_body
152+
{"message":"Authorization Failed"}
153+
--- error_log
154+
hmac-auth failed to authenticate the request, code: 401. error: client request can't be validated: algorithm missing
155+
156+
157+
158+
=== TEST 7: add consumer with username and jwt-auth plugins
159+
--- config
160+
location /t {
161+
content_by_lua_block {
162+
local t = require("lib.test_admin").test
163+
local code, body = t('/apisix/admin/consumers',
164+
ngx.HTTP_PUT,
165+
[[{
166+
"username": "jack",
167+
"plugins": {
168+
"jwt-auth": {
169+
"key": "user-key",
170+
"secret": "my-secret-key"
171+
}
172+
}
173+
}]]
174+
)
175+
176+
if code >= 300 then
177+
ngx.status = code
178+
end
179+
ngx.say(body)
180+
}
181+
}
182+
--- request
183+
GET /t
184+
--- response_body
185+
passed
186+
187+
188+
189+
=== TEST 8: test with expired jwt token
190+
--- request
191+
GET /hello
192+
--- error_code: 401
193+
--- response_body
194+
{"message":"Authorization Failed"}
195+
--- error_log
196+
jwt-auth failed to authenticate the request, code: 401. error: failed to verify jwt: 'exp' claim expired at Tue, 23 Jul 2019 08:28:21 GMT
197+
--- more_headers
198+
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTU2Mzg3MDUwMX0.pPNVvh-TQsdDzorRwa-uuiLYiEBODscp9wv0cwD6c68
199+
200+
201+
202+
=== TEST 9: test with jwt token containing wrong signature
203+
--- request
204+
GET /hello
205+
--- error_code: 401
206+
--- response_body
207+
{"message":"Authorization Failed"}
208+
--- error_log
209+
jwt-auth failed to authenticate the request, code: 401. error: failed to verify jwt: signature mismatch: fNtFJnNnJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs
210+
--- more_headers
211+
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNnJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs
212+
213+
214+
215+
=== TEST 10: verify jwt-auth
216+
--- request
217+
GET /hello
218+
--- more_headers
219+
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs
220+
--- response_body
221+
hello world
222+
--- no_error_log
223+
failed to authenticate the request

0 commit comments

Comments
 (0)