bug: multi-auth throws an error when using default configuration parameters
Current Behavior
When I configure a route with multi-auth plugin and don't set conf.header value explicitly, the plugin breaks and returns 500 Internal Server Error:
<html>
<head><title>500 Internal Server Error</title></head>
<body>
<center><h1>500 Internal Server Error</h1></center>
<hr><center>openresty</center>
<p><em>Powered by <a href="https://apisix.apache.org/">APISIX</a>.</em></p></body>
</html>
Expected Behavior
I expect to obtain the classic response 401 Unauthorized:
{"message":"Missing API key found in request"}
Error Logs
2024/07/25 12:18:47 [error] 75#75: *522943 lua entry thread aborted: runtime error: /usr/local/openresty/lualib/resty/core/request.lua:118: bad argument #1 to 'lower' (string expected, got nil)
stack traceback:
coroutine 0:
[C]: in function 'lower'
/usr/local/openresty/lualib/resty/core/request.lua:118: in function '__index'
/home/apisix/apisix_src/apisix/core/request.lua:110: in function 'header'
/home/apisix/apisix_src/apisix/plugins/key-auth.lua:71: in function 'rewrite'
/home/apisix/apisix_src/apisix/plugins/multi-auth.lua:71: in function 'phase_func'
/home/apisix/apisix_src/apisix/plugin.lua:1155: in function 'run_plugin'
/home/apisix/apisix_src/apisix/init.lua:696: in function 'http_access_phase'
access_by_lua(nginx.conf:319):2: in main chunk, client: ::1, server: _, request: "GET /httpbin/test/multi-auth/test1/ HTTP/1.1", host: "localhost:9080"
Steps to Reproduce
multi-auth Example
Setup the multi-auth test routes:
# With multi-auth and conf.header default value
curl -s -X PUT "http://127.0.0.1:9180/apisix/admin/routes/3" -d '
{
"uris": [ "/httpbin/test/multi-auth/test1/*" ],
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
},
"plugins": {
"proxy-rewrite": {
"regex_uri": [
"^/httpbin/test/multi-auth/test1/(.*)",
"/get"
],
"method": "GET"
},
"multi-auth":{
"auth_plugins":[
{
"basic-auth": {}
},
{
"key-auth": {
"hide_credentials":true
}
}
]
}
}
}
'
# With multi-auth and conf.header custom value
curl -s -X PUT "http://127.0.0.1:9180/apisix/admin/routes/4" -d '
{
"uris": [ "/httpbin/test/multi-auth/test2/*" ],
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
},
"plugins": {
"proxy-rewrite": {
"regex_uri": [
"^/httpbin/test/multi-auth/test2/(.*)",
"/get"
],
"method": "GET"
},
"multi-auth":{
"auth_plugins":[
{
"basic-auth": {}
},
{
"key-auth": {
"hide_credentials":true,
"header":"apikey"
}
}
]
}
}
}
'
Test:
curl -s -i "http://localhost:9080/httpbin/test/multi-auth/test1/" # This gives 500 Internal Server Error (see log message)
curl -s -i "http://localhost:9080/httpbin/test/multi-auth/test2/" # This works
key-auth Example
With simple key-auth plugin it works just fine:
# With key-auth and conf.header default value
curl -s -X PUT "http://127.0.0.1:9180/apisix/admin/routes/1" -d '
{
"uris": [ "/httpbin/test/key-auth/test1/*" ],
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
},
"plugins": {
"proxy-rewrite": {
"regex_uri": [
"^/httpbin/test/key-auth/test1/(.*)",
"/get"
],
"method": "GET"
},
"key-auth": {
"hide_credentials":true
}
}
}
'
# With key-auth and conf.header custom value
curl -s -X PUT "http://127.0.0.1:9180/apisix/admin/routes/2" -d '
{
"uris": [ "/httpbin/test/key-auth/test2/*" ],
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
},
"plugins": {
"proxy-rewrite": {
"regex_uri": [
"^/httpbin/test/key-auth/test2/(.*)",
"/get"
],
"method": "GET"
},
"key-auth": {
"hide_credentials":true,
"header":"apikey"
}
}
}
'
Test:
curl -s -i "http://localhost:9080/httpbin/test/key-auth/test1/" # This works
curl -s -i "http://localhost:9080/httpbin/test/key-auth/test2/" # This works
Environment
-
APISIX version (run
apisix version):3.9.1 -
Operating system (run
uname -a):Linux e911f1d22ca2 5.15.146.1-microsoft-standard-WSL2 #1 SMP Thu Jan 11 04:09:03 UTC 2024 x86_64 GNU/Linux (built from source, in custom Docker container, from `debian:bullseye-slim` image) -
OpenResty / Nginx version (run
openresty -Vornginx -V):nginx version: openresty/1.25.3.1 built by gcc 10.2.1 20210110 (Debian 10.2.1-6) built with OpenSSL 3.2.0 23 Nov 2023 TLS SNI support enabled configure arguments: --prefix=/usr/local/openresty/nginx --with-debug --with-cc-opt='-DNGX_LUA_USE_ASSERT -DNGX_LUA_ABORT_AT_PANIC -O2 -DAPISIX_RUNTIME_VER=1.2.0 -DNGX_GRPC_CLI_ENGINE_PATH=/usr/local/openresty/libgrpc_engine.so -DNGX_HTTP_GRPC_CLI_ENGINE_PATH=/usr/local/openresty/libgrpc_engine.so -DNGX_LUA_ABORT_AT_PANIC -I/usr/local/openresty/zlib/include -I/usr/local/openresty/pcre/include -I/usr/local/openresty/openssl3/include' --add-module=../ngx_devel_kit-0.3.3 --add-module=../echo-nginx-module-0.63 --add-module=../xss-nginx-module-0.06 --add-module=../ngx_coolkit-0.2 --add-module=../set-misc-nginx-module-0.33 --add-module=../form-input-nginx-module-0.12 --add-module=../encrypted-session-nginx-module-0.09 --add-module=../srcache-nginx-module-0.33 --add-module=../ngx_lua-0.10.26 --add-module=../ngx_lua_upstream-0.07 --add-module=../headers-more-nginx-module-0.37 --add-module=../array-var-nginx-module-0.06 --add-module=../memc-nginx-module-0.20 --add-module=../redis2-nginx-module-0.15 --add-module=../redis-nginx-module-0.3.9 --add-module=../ngx_stream_lua-0.0.14 --with-ld-opt='-Wl,-rpath,/usr/local/openresty/luajit/lib -Wl,-rpath,/usr/local/openresty/wasmtime-c-api/lib -L/usr/local/openresty/zlib/lib -L/usr/local/openresty/pcre/lib -L/usr/local/openresty/openssl3/lib -Wl,-rpath,/usr/local/openresty/zlib/lib:/usr/local/openresty/pcre/lib:/usr/local/openresty/openssl3/lib' --add-module=/tmp/tmp.PvubYudeuF/openresty-1.25.3.1/../mod_dubbo-1.0.2 --add-module=/tmp/tmp.PvubYudeuF/openresty-1.25.3.1/../ngx_multi_upstream_module-1.2.0 --add-module=/tmp/tmp.PvubYudeuF/openresty-1.25.3.1/../apisix-nginx-module-1.16.0 --add-module=/tmp/tmp.PvubYudeuF/openresty-1.25.3.1/../apisix-nginx-module-1.16.0/src/stream --add-module=/tmp/tmp.PvubYudeuF/openresty-1.25.3.1/../apisix-nginx-module-1.16.0/src/meta --add-module=/tmp/tmp.PvubYudeuF/openresty-1.25.3.1/../wasm-nginx-module-0.7.0 --add-module=/tmp/tmp.PvubYudeuF/openresty-1.25.3.1/../lua-var-nginx-module-v0.5.3 --add-module=/tmp/tmp.PvubYudeuF/openresty-1.25.3.1/../grpc-client-nginx-module-v0.5.0 --add-module=/tmp/tmp.PvubYudeuF/openresty-1.25.3.1/../lua-resty-events-0.2.0 --with-poll_module --with-pcre-jit --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_v2_module --with-http_v3_module --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module --with-http_stub_status_module --with-http_realip_module --with-http_addition_module --with-http_auth_request_module --with-http_secure_link_module --with-http_random_index_module --with-http_gzip_static_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-threads --with-compat --with-stream --without-pcre2 --with-http_ssl_module -
LuaRocks version, for installation issues (run
luarocks --version):/usr/local/bin/luarocks 3.8.0
If that behaviour is expected and multi-auth.auth_plugins are supposed to be configured explicitly, I would suggest to add a disclaimer or some kind of note in the documentation 👀
This also happens with jwt-auth.
Examples
-
multi-authwithjwt-authdefault values:curl -s -X PUT "http://127.0.0.1:9180/apisix/admin/routes/5" -d ' { "uris": [ "/httpbin/test/multi-auth/test3/*" ], "upstream": { "type": "roundrobin", "nodes": { "httpbin.org:80": 1 } }, "plugins": { "proxy-rewrite": { "regex_uri": [ "^/httpbin/test/multi-auth/test3/(.*)", "/get" ], "method": "GET" }, "multi-auth":{ "auth_plugins":[ { "basic-auth": {} }, { "key-auth": { "hide_credentials":true, "header":"apikey" } }, { "jwt-auth": { "hide_credentials":true } } ] } } } 'test:
curl -s -i "http://localhost:9080/httpbin/test/multi-auth/test3/" # This gives 500 Internal Server Error (see log message below)log message:
2024/07/25 12:55:15 [error] 849#849: *736191 lua entry thread aborted: runtime error: /usr/local/openresty/lualib/resty/core/request.lua:118: bad argument #1 to 'lower' (string expected, got nil) stack traceback: coroutine 0: [C]: in function 'lower' /usr/local/openresty/lualib/resty/core/request.lua:118: in function '__index' /home/apisix/apisix_src/apisix/core/request.lua:110: in function 'header' ...c/apisix/plugins/scm/builtin/apisix/plugins/jwt-auth.lua:182: in function 'fetch_jwt_token' ...c/apisix/plugins/scm/builtin/apisix/plugins/jwt-auth.lua:338: in function 'rewrite' /home/apisix/apisix_src/apisix/plugins/multi-auth.lua:71: in function 'phase_func' /home/apisix/apisix_src/apisix/plugin.lua:1155: in function 'run_plugin' /home/apisix/apisix_src/apisix/init.lua:696: in function 'http_access_phase' access_by_lua(nginx.conf:319):2: in main chunk, client: ::1, server: _, request: "GET /httpbin/test/multi-auth/test3/ HTTP/1.1", host: "localhost:9080" -
multi-authwithjwt-authand custom value forconf.header:curl -s -X PUT "http://127.0.0.1:9180/apisix/admin/routes/6" -d ' { "uris": [ "/httpbin/test/multi-auth/test4/*" ], "upstream": { "type": "roundrobin", "nodes": { "httpbin.org:80": 1 } }, "plugins": { "proxy-rewrite": { "regex_uri": [ "^/httpbin/test/multi-auth/test4/(.*)", "/get" ], "method": "GET" }, "multi-auth":{ "auth_plugins":[ { "basic-auth": {} }, { "key-auth": { "hide_credentials":true, "header":"apikey" } }, { "jwt-auth": { "hide_credentials":true, "header":"jwt" } } ] } } } 'test:
curl -s -i "http://localhost:9080/httpbin/test/multi-auth/test4/" # This gives 500 Internal Server Error (see log message below)log message:
2024/07/25 12:55:17 [error] 843#843: *736393 lua entry thread aborted: runtime error: ...c/apisix/plugins/scm/builtin/apisix/plugins/jwt-auth.lua:208: attempt to concatenate field 'cookie' (a nil valu e) stack traceback: coroutine 0: ...c/apisix/plugins/scm/builtin/apisix/plugins/jwt-auth.lua: in function 'fetch_jwt_token' ...c/apisix/plugins/scm/builtin/apisix/plugins/jwt-auth.lua:338: in function 'rewrite' /home/apisix/apisix_src/apisix/plugins/multi-auth.lua:71: in function 'phase_func' /home/apisix/apisix_src/apisix/plugin.lua:1155: in function 'run_plugin' /home/apisix/apisix_src/apisix/init.lua:696: in function 'http_access_phase' access_by_lua(nginx.conf:319):2: in main chunk, client: ::1, server: _, request: "GET /httpbin/test/multi-auth/test4/ HTTP/1.1", host: "localhost:9080" -
multi-authwithjwt-authand custom value for bothconf.headerandconf.cookie:curl -s -X PUT "http://127.0.0.1:9180/apisix/admin/routes/7" -d ' { "uris": [ "/httpbin/test/multi-auth/test5/*" ], "upstream": { "type": "roundrobin", "nodes": { "httpbin.org:80": 1 } }, "plugins": { "proxy-rewrite": { "regex_uri": [ "^/httpbin/test/multi-auth/test5/(.*)", "/get" ], "method": "GET" }, "multi-auth":{ "auth_plugins":[ { "basic-auth": {} }, { "key-auth": { "hide_credentials":true, "header":"apikey" } }, { "jwt-auth": { "hide_credentials":true, "header":"jwt", "cookie":"jwt" } } ] } } } 'test:
curl -s -i "http://localhost:9080/httpbin/test/multi-auth/test5/" # This works
Hi @mikyll, thanks for your report. We will check and update here. (cc @bzp2010)
This problem should have been fixed by this PR https://github.com/apache/apisix/pull/11145, but it seems that this modification is not included in version 3.9.1 https://github.com/apache/apisix/commits/3.9.1/
This problem should have been fixed by this PR #11145, but it seems that this modification is not included in version 3.9.1 https://github.com/apache/apisix/commits/3.9.1/
#11145 will be included in 3.10