diff --git a/apisix/plugins/opa.lua b/apisix/plugins/opa.lua index 1b7db1b62d73..24bdb5be1a46 100644 --- a/apisix/plugins/opa.lua +++ b/apisix/plugins/opa.lua @@ -19,6 +19,7 @@ local core = require("apisix.core") local http = require("resty.http") local helper = require("apisix.plugins.opa.helper") local type = type +local ipairs = ipairs local schema = { type = "object", @@ -37,6 +38,14 @@ local schema = { description = "timeout in milliseconds", }, keepalive = {type = "boolean", default = true}, + send_headers_upstream = { + type = "array", + minItems = 1, + items = { + type = "string" + }, + description = "list of headers to pass to upstream in request" + }, keepalive_timeout = {type = "integer", minimum = 1000, default = 60000}, keepalive_pool = {type = "integer", minimum = 1, default = 5}, with_route = {type = "boolean", default = false}, @@ -125,6 +134,14 @@ function _M.access(conf, ctx) end return status_code, reason + else if result.headers and conf.send_headers_upstream then + for _, name in ipairs(conf.send_headers_upstream) do + local value = result.headers[name] + if value then + core.request.set_header(ctx, name, value) + end + end + end end end diff --git a/ci/pod/opa/example.rego b/ci/pod/opa/example.rego index 2eb912e08c52..a9161042b887 100644 --- a/ci/pod/opa/example.rego +++ b/ci/pod/opa/example.rego @@ -29,6 +29,11 @@ allow { request.query["user"] } +allow { + request.method == "GET" + startswith(request.path, "/echo") +} + reason = users[request.query["user"]].reason { not allow request.query["user"] @@ -39,6 +44,11 @@ headers = users[request.query["user"]].headers { request.query["user"] } +headers = {"user": request.query["user"]} { + allow + request.query["user"] +} + status_code = users[request.query["user"]].status_code { not allow request.query["user"] diff --git a/t/plugin/opa.t b/t/plugin/opa.t index 9354b35d1043..9d731ae0682c 100644 --- a/t/plugin/opa.t +++ b/t/plugin/opa.t @@ -179,3 +179,47 @@ test-header: only-for-test --- error_code: 403 --- response {"code":40001,"desc":"Give you a object reason"} + + + +=== TEST 12: setup route with plugin +--- 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": { + "opa": { + "host": "http://127.0.0.1:8181", + "policy": "example", + "send_headers_upstream": ["user"] + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uris": ["/echo"] + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 13: hit route +--- request +GET /echo?test=1234&user=none +--- response_headers +user: none