blob: c28fad3075a7aea287d41877e680238cc5636552 [file] [log] [blame]
#
# 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.
#
BEGIN {
$ENV{VAULT_TOKEN} = "root";
}
use t::APISIX 'no_plan';
repeat_each(1);
no_long_string();
no_root_location();
no_shuffle();
add_block_preprocessor(sub {
my ($block) = @_;
if ((!defined $block->error_log) && (!defined $block->no_error_log)) {
$block->set_value("no_error_log", "[error]");
}
if (!defined $block->request) {
$block->set_value("request", "GET /t");
if (!$block->response_body) {
$block->set_value("response_body", "passed\n");
}
}
});
run_tests;
__DATA__
=== TEST 1: add consumer with username and plugins
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/consumers',
ngx.HTTP_PUT,
[[{
"username": "jack",
"plugins": {
"jwt-auth": {
"key": "user-key",
"secret": "my-secret-key"
}
}
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
=== TEST 2: enable jwt auth plugin using admin api with custom parameter
--- 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": {
"jwt-auth": {
"header": "jwt-header",
"query": "jwt-query",
"cookie": "jwt-cookie",
"hide_credentials": false
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/echo"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
=== TEST 3: verify (in header) not hiding credentials
--- request
GET /echo
--- more_headers
jwt-header: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs
--- response_headers
jwt-header: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs
=== TEST 4: verify (in cookie) not hiding credentials
--- request
GET /echo
--- more_headers
Cookie: jwt-cookie=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs
--- response_headers
Cookie: jwt-cookie=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs
=== TEST 5: enable jwt auth plugin using admin api without 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": {
"jwt-auth": {
"header": "jwt-header",
"query": "jwt-query",
"cookie": "jwt-cookie",
"hide_credentials": false
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/plugin_proxy_rewrite_args"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
=== TEST 6: verify (in query) without hiding credentials
--- request
GET /plugin_proxy_rewrite_args?foo=bar&hello=world&jwt-query=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs
--- response_body
uri: /plugin_proxy_rewrite_args
foo: bar
hello: world
jwt-query: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs
=== TEST 7: enable jwt auth plugin using admin api 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": {
"jwt-auth": {
"header": "jwt-header",
"query": "jwt-query",
"cookie": "jwt-cookie",
"hide_credentials": true
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/echo"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
=== TEST 8: verify (in header) with hiding credentials
--- request
GET /echo
--- more_headers
jwt-header: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs
--- response_headers
!jwt-header
=== TEST 9: enable jwt auth plugin using admin api 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": {
"jwt-auth": {
"header": "jwt-header",
"query": "jwt-query",
"cookie": "jwt-cookie",
"hide_credentials": true
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/plugin_proxy_rewrite_args"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
=== TEST 10: verify (in query) with hiding credentials
--- request
GET /plugin_proxy_rewrite_args?foo=bar&hello=world&jwt-query=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs
--- response_body
uri: /plugin_proxy_rewrite_args
foo: bar
hello: world
=== TEST 11: verify (in cookie) 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": {
"jwt-auth": {
"header": "jwt-header",
"query": "jwt-query",
"cookie": "jwt-cookie",
"hide_credentials": true
}
},
"upstream": {
"nodes": {
"test.com:1980": 1
},
"type": "roundrobin"
},
"uri": "/hello"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
=== TEST 12: verify (in cookie) with hiding credentials
--- request
GET /hello
--- more_headers
Cookie: hello=world; jwt-cookie=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs; foo=bar
--- response_body
hello world
=== TEST 13: delete exist consumers
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
-- delete exist consumers
local code, body = t('/apisix/admin/consumers/jack', ngx.HTTP_DELETE)
ngx.say(body)
}
}
--- response_body
passed
=== TEST 14: data encryption for secret
--- yaml_config
apisix:
data_encryption:
enable_encrypt_fields: true
keyring:
- edd1c9f0985e76a2
--- config
location /t {
content_by_lua_block {
local json = require("toolkit.json")
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/consumers',
ngx.HTTP_PUT,
[[{
"username": "jack",
"plugins": {
"jwt-auth": {
"key": "user-key",
"secret": "my-secret-key"
}
}
}]]
)
if code >= 300 then
ngx.status = code
ngx.say(body)
return
end
ngx.sleep(0.1)
-- get plugin conf from admin api, password is decrypted
local code, message, res = t('/apisix/admin/consumers/jack',
ngx.HTTP_GET
)
res = json.decode(res)
if code >= 300 then
ngx.status = code
ngx.say(message)
return
end
ngx.say(res.value.plugins["jwt-auth"].secret)
-- get plugin conf from etcd, password is encrypted
local etcd = require("apisix.core.etcd")
local res = assert(etcd.get('/consumers/jack'))
ngx.say(res.body.node.value.plugins["jwt-auth"].secret)
}
}
--- response_body
my-secret-key
IRWpPjbDq5BCgHyIllnOMA==
=== TEST 15: data encryption for private_key
--- yaml_config
apisix:
data_encryption:
enable_encrypt_fields: true
keyring:
- edd1c9f0985e76a2
--- config
location /t {
content_by_lua_block {
local json = require("toolkit.json")
local t = require("lib.test_admin").test
-- dletet exist consumers
t('/apisix/admin/consumers/jack', ngx.HTTP_DELETE)
local code, body = t('/apisix/admin/consumers',
ngx.HTTP_PUT,
[[{
"username": "jack",
"plugins": {
"jwt-auth": {
"key": "user-key-rs256",
"algorithm": "RS256",
"public_key": "-----BEGIN PUBLIC KEY-----\nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKebDxlvQMGyEesAL1r1nIJBkSdqu3Hr\n7noq/0ukiZqVQLSJPMOv0oxQSutvvK3hoibwGakDOza+xRITB7cs2cECAwEAAQ==\n-----END PUBLIC KEY-----",
"private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIBOgIBAAJBAKebDxlvQMGyEesAL1r1nIJBkSdqu3Hr7noq/0ukiZqVQLSJPMOv\n0oxQSutvvK3hoibwGakDOza+xRITB7cs2cECAwEAAQJAYPWh6YvjwWobVYC45Hz7\n+pqlt1DWeVQMlN407HSWKjdH548ady46xiQuZ5Cfx3YyCcnsfVWaQNbC+jFbY4YL\nwQIhANfASwz8+2sKg1xtvzyaChX5S5XaQTB+azFImBJumixZAiEAxt93Td6JH1RF\nIeQmD/K+DClZMqSrliUzUqJnCPCzy6kCIAekDsRh/UF4ONjAJkKuLedDUfL3rNFb\n2M4BBSm58wnZAiEAwYLMOg8h6kQ7iMDRcI9I8diCHM8yz0SfbfbsvzxIFxECICXs\nYvIufaZvBa8f+E/9CANlVhm5wKAyM8N8GJsiCyEG\n-----END RSA PRIVATE KEY-----"
}
}
}]]
)
if code >= 300 then
ngx.status = code
ngx.say(body)
return
end
ngx.sleep(0.1)
-- get plugin conf from admin api, password is decrypted
local code, message, res = t('/apisix/admin/consumers/jack',
ngx.HTTP_GET
)
res = json.decode(res)
if code >= 300 then
ngx.status = code
ngx.say(message)
return
end
ngx.say(res.value.plugins["jwt-auth"].private_key)
-- get plugin conf from etcd, password is encrypted
local etcd = require("apisix.core.etcd")
local res = assert(etcd.get('/consumers/jack'))
ngx.say(res.body.node.value.plugins["jwt-auth"].private_key)
}
}
--- response_body
-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBAKebDxlvQMGyEesAL1r1nIJBkSdqu3Hr7noq/0ukiZqVQLSJPMOv
0oxQSutvvK3hoibwGakDOza+xRITB7cs2cECAwEAAQJAYPWh6YvjwWobVYC45Hz7
+pqlt1DWeVQMlN407HSWKjdH548ady46xiQuZ5Cfx3YyCcnsfVWaQNbC+jFbY4YL
wQIhANfASwz8+2sKg1xtvzyaChX5S5XaQTB+azFImBJumixZAiEAxt93Td6JH1RF
IeQmD/K+DClZMqSrliUzUqJnCPCzy6kCIAekDsRh/UF4ONjAJkKuLedDUfL3rNFb
2M4BBSm58wnZAiEAwYLMOg8h6kQ7iMDRcI9I8diCHM8yz0SfbfbsvzxIFxECICXs
YvIufaZvBa8f+E/9CANlVhm5wKAyM8N8GJsiCyEG
-----END RSA PRIVATE KEY-----
HrMHUvE9Esvn7GnZ+vAynaIg/8wlB3r0zm0htmnwofYPZeBpLnpW3iN9UtQG4ZIBYRZih6EBuRK8W3Kychw/SgjIFuzVeTFowBCUfd1wZ4Q+frUOLZ0Xmkh8j3yHUprnh+d9PA8EHCEapdkWY3psJj6rTgrREzjDEVf/TV3EjjfgG16ih5/c3TChApLXwfEwfBp5APSf7kzMccCRbA4bXvMDsQSQAwVsRD8cjJkSdHTvuzfg1g8xoCy4I05DsMM8CybJAd+BDZnJxhrGIQaItu5/0XQJy+uy/niOpzYYN+NDX+8fl65VUxdUtqXF82ChRlmGP3+zKN7epufAsL/36pHOnS73Q7WBKRxyyA16BEBk0wK7rI+KemBfG5YFXjcBnPkxYssSudqhmlcr6e5Tl0LhVj/BIj94fVE3/EJ+NO3BJMrlhjorilrQKAsiCWujWSqAK7gtAp3YEO//yOygh/p8gh22NdIV0ykGAx4QNKINUgdgh+g8DdykNGLGStH8TPUs8GmzV7nxvw/0cbiocLps6uk0VjjVUqUAvOdwpbiRwv6effPUB6cxW3G6QllBbTP8I+eoFIRfYd6cFJPpX1AtISfNZw459WarwZmHrZGOQU4iKlyl2yLcKY634Fx5JykUY5YP+MYYDHbIcD2gxA==
=== TEST 16: set jwt-auth conf: secret uses secret ref
--- request
GET /t
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
-- put secret vault config
local code, body = t('/apisix/admin/secrets/vault/test1',
ngx.HTTP_PUT,
[[{
"uri": "http://127.0.0.1:8200",
"prefix" : "kv/apisix",
"token" : "root"
}]]
)
if code >= 300 then
ngx.status = code
return ngx.say(body)
end
-- change consumer with secrets ref: vault
code, body = t('/apisix/admin/consumers',
ngx.HTTP_PUT,
[[{
"username": "jack",
"plugins": {
"jwt-auth": {
"key": "user-key",
"secret": "$secret://vault/test1/jack/secret"
}
}
}]]
)
if code >= 300 then
ngx.status = code
return ngx.say(body)
end
-- set route
code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"plugins": {
"jwt-auth": {
"header": "jwt-header",
"query": "jwt-query",
"cookie": "jwt-cookie",
"hide_credentials": false
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/echo"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- response_body
passed
=== TEST 17: store secret into vault
--- exec
VAULT_TOKEN='root' VAULT_ADDR='http://0.0.0.0:8200' vault kv put kv/apisix/jack secret=my-secret-key
--- response_body
Success! Data written to: kv/apisix/jack
=== TEST 18: verify (in header) not hiding credentials
--- request
GET /echo
--- more_headers
jwt-header: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs
--- response_headers
jwt-header: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs
=== TEST 19: store rsa key pairs and secret into vault from local filesystem
--- exec
VAULT_TOKEN='root' VAULT_ADDR='http://0.0.0.0:8200' vault kv put kv/apisix/rsa1 secret=$3nsitiv3-c8d3 public_key=@t/certs/public.pem private_key=@t/certs/private.pem
--- response_body
Success! Data written to: kv/apisix/rsa1
=== TEST 20: create consumer for RS256 algorithm with private/public key fetched from vault and public key in consumer schema
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
-- enable jwt auth plugin using admin api
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"plugins": {
"jwt-auth": {}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/hello"
}]]
)
if code >= 300 then
ngx.status = code
return ngx.say(body)
end
-- create public API route (jwt-auth sign)
local code, body = t('/apisix/admin/routes/2',
ngx.HTTP_PUT,
[[{
"plugins": {
"public-api": {}
},
"uri": "/apisix/plugin/jwt/sign"
}]]
)
if code >= 300 then
ngx.status = code
return ngx.say(body)
end
local code, body = t('/apisix/admin/consumers',
ngx.HTTP_PUT,
[[{
"username": "john",
"plugins": {
"jwt-auth": {
"key": "rsa1",
"algorithm": "RS256",
"secret": "$secret://vault/test1/rsa1/secret",
"public_key": "$secret://vault/test1/rsa1/public_key",
"private_key": "$secret://vault/test1/rsa1/private_key"
}
}
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- response_body
passed
=== TEST 21: sign a jwt with with rsa key pair and access /hello
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, err, sign = t('/apisix/plugin/jwt/sign?key=rsa1',
ngx.HTTP_GET
)
if code > 200 then
ngx.status = code
ngx.say(err)
return
end
local code, _, res = t('/hello?jwt=' .. sign,
ngx.HTTP_GET
)
if code >= 300 then
ngx.status = code
end
ngx.print(res)
}
}
--- response_body
hello world
=== TEST 22: set jwt-auth conf with the token in an env var: secret uses secret ref
--- request
GET /t
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
-- put secret vault config
local code, body = t('/apisix/admin/secrets/vault/test1',
ngx.HTTP_PUT,
[[{
"uri": "http://127.0.0.1:8200",
"prefix" : "kv/apisix",
"token" : "$ENV://VAULT_TOKEN"
}]]
)
if code >= 300 then
ngx.status = code
return ngx.say(body)
end
-- change consumer with secrets ref: vault
code, body = t('/apisix/admin/consumers',
ngx.HTTP_PUT,
[[{
"username": "jack",
"plugins": {
"jwt-auth": {
"key": "user-key",
"secret": "$secret://vault/test1/jack/secret"
}
}
}]]
)
if code >= 300 then
ngx.status = code
return ngx.say(body)
end
-- set route
code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"plugins": {
"jwt-auth": {
"header": "jwt-header",
"query": "jwt-query",
"cookie": "jwt-cookie",
"hide_credentials": false
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/echo"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- response_body
passed
=== TEST 23: verify (in header) not hiding credentials
--- request
GET /echo
--- more_headers
jwt-header: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs
--- response_headers
jwt-header: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs