Skip to content

Commit

Permalink
Merge branch 'master' of github.com:apache/apisix into revolyssup/bac…
Browse files Browse the repository at this point in the history
…kport/anonymousconsumer
  • Loading branch information
Revolyssup committed Dec 13, 2024
2 parents e4f9572 + 1f89705 commit 74a2748
Show file tree
Hide file tree
Showing 28 changed files with 742 additions and 80 deletions.
3 changes: 2 additions & 1 deletion apisix-master-0.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ dependencies = {
"lua-resty-cookie = 0.2.0-1",
"lua-resty-session = 3.10",
"opentracing-openresty = 0.1",
"lua-resty-radixtree = 2.9.1",
"lua-resty-radixtree = 2.9.2",
"lua-protobuf = 0.5.2-1",
"lua-resty-openidc = 1.7.6-3",
"luafilesystem = 1.7.0-2",
Expand Down Expand Up @@ -83,6 +83,7 @@ dependencies = {
"brotli-ffi = 0.3-1",
"lua-ffi-zlib = 0.6-0",
"api7-lua-resty-aws == 2.0.2-1",
"multipart = 0.5.9-1",
}

build = {
Expand Down
36 changes: 28 additions & 8 deletions apisix/cli/ops.lua
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ local str_find = string.find
local str_byte = string.byte
local str_sub = string.sub
local str_format = string.format
local string = string
local table = table


local _M = {}

Expand Down Expand Up @@ -502,17 +505,34 @@ Please modify "admin_key" in conf/config.yaml .


if yaml_conf.apisix.ssl.ssl_trusted_certificate ~= nil then
local cert_path = yaml_conf.apisix.ssl.ssl_trusted_certificate
-- During validation, the path is relative to PWD
-- When Nginx starts, the path is relative to conf
-- Therefore we need to check the absolute version instead
cert_path = pl_path.abspath(cert_path)
local cert_paths = {}
local ssl_certificates = yaml_conf.apisix.ssl.ssl_trusted_certificate
for cert_path in string.gmatch(ssl_certificates, '([^,]+)') do
cert_path = util.trim(cert_path)
if cert_path == "system" then
local trusted_certs_path, err = util.get_system_trusted_certs_filepath()
if not trusted_certs_path then
util.die(err)
end
table.insert(cert_paths, trusted_certs_path)
else
-- During validation, the path is relative to PWD
-- When Nginx starts, the path is relative to conf
-- Therefore we need to check the absolute version instead
cert_path = pl_path.abspath(cert_path)
if not pl_path.exists(cert_path) then
util.die("certificate path", cert_path, "doesn't exist\n")
end

if not pl_path.exists(cert_path) then
util.die("certificate path", cert_path, "doesn't exist\n")
table.insert(cert_paths, cert_path)
end
end

yaml_conf.apisix.ssl.ssl_trusted_certificate = cert_path
local combined_cert_filepath = yaml_conf.apisix.ssl.ssl_trusted_combined_path
or "/usr/local/apisix/conf/ssl_trusted_combined.pem"
util.gen_trusted_certs_combined_file(combined_cert_filepath, cert_paths)

yaml_conf.apisix.ssl.ssl_trusted_certificate = combined_cert_filepath
end

-- enable ssl with place holder crt&key
Expand Down
3 changes: 3 additions & 0 deletions apisix/cli/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,9 @@ local config_schema = {
ssl_trusted_certificate = {
type = "string",
},
ssl_trusted_combined_path = {
type = "string",
},
listen = {
type = "array",
items = {
Expand Down
53 changes: 53 additions & 0 deletions apisix/cli/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ local exit = os.exit
local stderr = io.stderr
local str_format = string.format
local tonumber = tonumber
local io = io
local ipairs = ipairs
local assert = assert

local _M = {}

Expand Down Expand Up @@ -133,4 +136,54 @@ function _M.file_exists(file_path)
return f ~= nil and close(f)
end

do
local trusted_certs_paths = {
"/etc/ssl/certs/ca-certificates.crt", -- Debian/Ubuntu/Gentoo
"/etc/pki/tls/certs/ca-bundle.crt", -- Fedora/RHEL 6
"/etc/ssl/ca-bundle.pem", -- OpenSUSE
"/etc/pki/tls/cacert.pem", -- OpenELEC
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", -- CentOS/RHEL 7
"/etc/ssl/cert.pem", -- OpenBSD, Alpine
}

-- Check if a file exists using Lua's built-in `io.open`
local function file_exists(path)
local file = io.open(path, "r")
if file then
file:close()
return true
else
return false
end
end

function _M.get_system_trusted_certs_filepath()
for _, path in ipairs(trusted_certs_paths) do
if file_exists(path) then
return path
end
end

return nil,
"Could not find trusted certs file in " ..
"any of the `system`-predefined locations. " ..
"Please install a certs file there or set " ..
"`lua_ssl_trusted_certificate` to a " ..
"specific file path instead of `system`"
end
end


function _M.gen_trusted_certs_combined_file(combined_filepath, paths)
local combined_file = assert(io.open(combined_filepath, "w"))
for _, path in ipairs(paths) do
local cert_file = assert(io.open(path, "r"))
combined_file:write(cert_file:read("*a"))
combined_file:write("\n")
cert_file:close()
end
combined_file:close()
end


return _M
23 changes: 21 additions & 2 deletions apisix/plugins/body-transformer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@ local type = type
local pcall = pcall
local pairs = pairs
local next = next
local multipart = require("multipart")
local setmetatable = setmetatable

local transform_schema = {
type = "object",
properties = {
input_format = { type = "string", enum = {"xml", "json", "encoded", "args", "plain"} },
input_format = { type = "string",
enum = {"xml", "json", "encoded", "args", "plain", "multipart",}},
template = { type = "string" },
template_is_base64 = { type = "boolean" },
},
Expand Down Expand Up @@ -118,6 +120,10 @@ local decoders = {
args = function()
return req_get_uri_args()
end,
multipart = function (data, content_type_header)
local res = multipart(data, content_type_header)
return res
end
}


Expand All @@ -128,11 +134,20 @@ end

local function transform(conf, body, typ, ctx, request_method)
local out = {}
local _multipart
local format = conf[typ].input_format
local ct = ctx.var.http_content_type
if typ == "response" then
ct = ngx.header.content_type
end
if (body or request_method == "GET") and format ~= "plain" then
local err
if format then
out, err = decoders[format](body)
out, err = decoders[format](body, ct)
if format == "multipart" then
_multipart = out
out = out:get_all_with_arrays()
end
if not out then
err = str_format("%s body decode: %s", typ, err)
core.log.error(err, ", body=", body)
Expand Down Expand Up @@ -160,7 +175,9 @@ local function transform(conf, body, typ, ctx, request_method)
_body = body,
_escape_xml = escape_xml,
_escape_json = escape_json,
_multipart = _multipart
}})

local ok, render_out = pcall(render, out)
if not ok then
local err = str_format("%s template rendering: %s", typ, render_out)
Expand All @@ -184,6 +201,8 @@ local function set_input_format(conf, typ, ct, method)
conf[typ].input_format = "json"
elseif str_find(ct:lower(), "application/x-www-form-urlencoded", nil, true) then
conf[typ].input_format = "encoded"
elseif str_find(ct:lower(), "multipart/", nil, true) then
conf[typ].input_format = "multipart"
end
end
end
Expand Down
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
18 changes: 11 additions & 7 deletions apisix/plugins/workflow.lua
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ local schema = {
}
}
},
required = {"case", "actions"}
required = {"actions"}
}
}
},
Expand Down Expand Up @@ -117,9 +117,11 @@ function _M.check_schema(conf)
end

for idx, rule in ipairs(conf.rules) do
local ok, err = expr.new(rule.case)
if not ok then
return false, "failed to validate the 'case' expression: " .. err
if rule.case then
local ok, err = expr.new(rule.case)
if not ok then
return false, "failed to validate the 'case' expression: " .. err
end
end

local actions = rule.actions
Expand All @@ -143,10 +145,12 @@ end


function _M.access(conf, ctx)
local match_result
for _, rule in ipairs(conf.rules) do
local expr, _ = expr.new(rule.case)
match_result = expr:eval(ctx.var)
local match_result = true
if rule.case then
local expr, _ = expr.new(rule.case)
match_result = expr:eval(ctx.var)
end
if match_result then
-- only one action is currently supported
local action = rule.actions[1]
Expand Down
8 changes: 8 additions & 0 deletions ci/linux_openresty_common_runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,15 @@ do_install() {
# sudo apt-get install tree -y
# tree deps

# The latest version of test-nginx is not compatible with the current set of tests with ---http2
# due to this commit: https://github.com/openresty/test-nginx/commit/0ccd106cbe6878318e5a591634af8f1707c411a6
# This change pins test-nginx to a commit before this one.
git clone --depth 1 https://github.com/openresty/test-nginx.git test-nginx
cd test-nginx
git fetch --depth=1 origin ced30a31bafab6c68873efb17b6d80f39bcd95f5
git checkout ced30a31bafab6c68873efb17b6d80f39bcd95f5
cd ..

make utils

mkdir -p build-cache
Expand Down
10 changes: 6 additions & 4 deletions conf/config.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@ apisix:
# - ip: 127.0.0.3 # If not set, default to `0.0.0.0`.
# port: 9445
# enable_http3: true
# ssl_trusted_certificate: /path/to/ca-cert # Set the path to CA certificates used to verify client
# certificates in the PEM format.
ssl_trusted_combined_path: /usr/local/apisix/conf/ssl_trusted_combined.pem # All the trusted certificates will be combined into a single file
#ssl_trusted_certificate: system # Specifies comma separated list of trusted CA. Value can be either "system"(for using system available ca certs) or
# a file path with trusted CA certificates in the PEM format
ssl_protocols: TLSv1.2 TLSv1.3 # TLS versions supported.
ssl_ciphers: ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl_session_tickets: false # If true, session tickets are used for SSL/TLS connections.
Expand Down Expand Up @@ -610,8 +611,9 @@ plugin_attr: # Plugin attributes
# - 100
# - 200
# - 500
# expire: 0 # The expiration time after metrics become inactive, unit: second.
# 0 means the metrics will not expire
# expire: 0 # The expiration time of metrics in seconds.
# 0 means the metrics will not expire.
# Only affect apisix_http_status, apisix_bandwidth, and apisix_http_latency.
# If you need to set the expiration time, it is recommended to use 600, which is 10 minutes.
server-info: # Plugin: server-info
report_ttl: 60 # Set the TTL in seconds for server info in etcd.
Expand Down
34 changes: 17 additions & 17 deletions docs/en/latest/admin-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -913,25 +913,25 @@ Prerequisite: Consumer `jack` has been created.
Create the `key-auth` Credential for consumer `jack`:
```shell
curl http://127.0.0.1:9180/apisix/admin/consumers/jack/credentials/auth-one \
-H "X-API-KEY: $admin_key" -X PUT -i -d '
{
"plugins": {
"key-auth": {
"key": "auth-one"
}
```shell
curl http://127.0.0.1:9180/apisix/admin/consumers/jack/credentials/auth-one \
-H "X-API-KEY: $admin_key" -X PUT -i -d '
{
"plugins": {
"key-auth": {
"key": "auth-one"
}
}'
```
}
}'
```
```
HTTP/1.1 200 OK
Date: Thu, 26 Dec 2019 08:17:49 GMT
...
```
HTTP/1.1 200 OK
Date: Thu, 26 Dec 2019 08:17:49 GMT
...
{"key":"\/apisix\/consumers\/jack\/credentials\/auth-one","value":{"update_time":1666260780,"plugins":{"key-auth":{"key":"auth-one"}},"create_time":1666260780}}
```
{"key":"\/apisix\/consumers\/jack\/credentials\/auth-one","value":{"update_time":1666260780,"plugins":{"key-auth":{"key":"auth-one"}},"create_time":1666260780}}
```
## Upstream
Expand Down Expand Up @@ -1278,7 +1278,7 @@ For notes on ID syntax please refer to: [ID Syntax](#quick-note-on-id-syntax)
| labels | False | Match Rules | Attributes of the resource specified as key-value pairs. | {"version":"v2","build":"16","env":"production"} |
| type | False | Auxiliary | Identifies the type of certificate, default `server`. | `client` Indicates that the certificate is a client certificate, which is used when APISIX accesses the upstream; `server` Indicates that the certificate is a server-side certificate, which is used by APISIX when verifying client requests. |
| status | False | Auxiliary | Enables the current SSL. Set to `1` (enabled) by default. | `1` to enable, `0` to disable |
| ssl_protocols | False | An array of ssl protocols | It is used to control the SSL/TLS protocol version used between servers and clients. See [SSL Protocol](./ssl-protocol.md) for more examples. | `["TLSv1.2", "TLSv2.3"]` |
| ssl_protocols | False | An array of ssl protocols | It is used to control the SSL/TLS protocol version used between servers and clients. See [SSL Protocol](./ssl-protocol.md) for more examples. | `["TLSv1.1", "TLSv1.2", "TLSv1.3"]` |
Example Configuration:
Expand Down
14 changes: 7 additions & 7 deletions docs/en/latest/plugins/jwt-auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,18 @@ For Consumer:
| exp | integer | False | 86400 | [1,...] | Expiry time of the token in seconds. |
| base64_secret | boolean | False | false | | Set to true if the secret is base64 encoded. |
| lifetime_grace_period | integer | False | 0 | [0,...] | Define the leeway in seconds to account for clock skew between the server that generated the jwt and the server validating it. Value should be zero (0) or a positive integer. |
| key_claim_name | string | False | key | | The name of the JWT claim that contains the user key (corresponds to Consumer's key attribute). |

NOTE: `encrypt_fields = {"secret"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).

For Route:

| Name | Type | Required | Default | Description |
|--------|--------|----------|---------------|---------------------------------------------------------------------|
| header | string | False | authorization | The header to get the token from. |
| query | string | False | jwt | The query string to get the token from. Lower priority than header. |
| cookie | string | False | jwt | The cookie to get the token from. Lower priority than query. |
| hide_credentials | boolean | False | false | Set to true will not pass the authorization request of header\query\cookie to the Upstream.|
| Name | Type | Required | Default | Description |
|------------------|---------|----------|---------------|-------------------------------------------------------------------------------------------------|
| header | string | False | authorization | The header to get the token from. |
| query | string | False | jwt | The query string to get the token from. Lower priority than header. |
| cookie | string | False | jwt | The cookie to get the token from. Lower priority than query. |
| hide_credentials | boolean | False | false | Set to true will not pass the authorization request of header\query\cookie to the Upstream. |
| key_claim_name | string | False | key | The name of the JWT claim that contains the user key (corresponds to Consumer's key attribute). |

You can implement `jwt-auth` with [HashiCorp Vault](https://www.vaultproject.io/) to store and fetch secrets and RSA keys pairs from its [encrypted KV engine](https://developer.hashicorp.com/vault/docs/secrets/kv) using the [APISIX Secret](../terminology/secret.md) resource.

Expand Down
Loading

0 comments on commit 74a2748

Please sign in to comment.