Open Policy Agent(OPA)是一个开源的轻量级通用策略引擎,能够代替软件中内置的策略功能模块,帮忙用户实现服务与策略引擎的解耦。得益于 OPA 欠缺的生态系统,用户能够很容易地集成 OPA 和其余服务,例如程序库、HTTP API 等。
如下图所示,OPA 首先通过策略语言 Rego 形容策略;而后通过 JSON 存储策略数据,之后用户就能够发送查问申请。收到查问申请后,OPA 将联合策略、数据和用户输出的查问申请内容生成策略决策,并将决策发送至服务。
插件介绍
Apache APISIX 提供了一个 opa
插件,用户能够应用这个插件,便捷地将 OPA 提供的策略能力引入到 Apache APISIX,实现灵便的身份认证与准入管制性能。
将 opa
插件配置在路由上后,Apache APISIX 会在解决响应申请时,将申请信息、连贯信息等组装成 JSON 数据,并将其发送到策略决策 API 地址。只有在 OPA 中部署的策略合乎 Apache APISIX 设定的数据标准,就能够实现如通过申请、拒绝请求、自定义状态码、自定义响应头、自定义响应头等性能。
本文以 HTTP API 为例为大家介绍 opa
插件,并具体阐明如何将 Apache APISIX 与 OPA 进行集成,实现后端服务的认证受权解耦。
如何应用
步骤一:搭建测试环境
- 应用 Docker 构建 OPA 服务。
# 应用 Docker 运行 OPA
docker run -d --name opa -p 8181:8181 openpolicyagent/opa:0.35.0 run -s
- 创立
example
策略。
# 创立策略
curl -XPUT 'localhost:8181/v1/policies/example' \
--header 'Content-Type: text/plain' \
--data-raw 'package example
import input.request
import data.users
default allow = false
allow {
# 具备名为 test-header 值为 only-for-test 申请头
request.headers["test-header"] == "only-for-test"
# 申请办法为 GET
request.method == "GET"
# 申请门路以 /get 结尾
startswith(request.path, "/get")
# GET 参数 test 存在且不等于 abcd
request.query["test"] != "abcd"
# GET 参数 user 存在
request.query["user"]
}
reason = users[request.query["user"]].reason {
not allow
request.query["user"]
}
headers = users[request.query["user"]].headers {
not allow
request.query["user"]
}
status_code = users[request.query["user"]].status_code {
not allow
request.query["user"]
}'
- 创立
users
数据。
# 创立测试用户数据
curl -XPUT 'localhost:8181/v1/data/users' \
--header 'Content-Type: application/json' \
--data-raw '{"alice": {"headers": {"Location":"http://example.com/auth"},"status_code": 302
},
"bob": {
"headers": {
"test": "abcd",
"abce": "test"
}
},
"carla": {"reason": "Give you a string reason"},
"dylon": {
"headers": {"Content-Type": "application/json"},
"reason": {
"code": 40001,
"desc": "Give you a object reason"
}
}
}'
步骤二:创立路由并开启 opa
插件
curl -XPUT 'http://127.0.0.1:9080/apisix/admin/routes/r1' \
--header 'X-API-KEY: <api-key>' \
--header 'Content-Type: application/json' \
--data-raw '{"uri":"/*","methods": ["GET","POST","PUT","DELETE"],"plugins": {"opa": {"host":"http://127.0.0.1:8181","policy":"example"}
},
"upstream": {
"nodes": {"httpbin.org:80": 1},
"type": "roundrobin"
}
}'
步骤三:测试申请
# 容许申请
curl -XGET '127.0.0.1:9080/get?test=none&user=dylon' \
--header 'test-header: only-for-test'
{
"args": {
"test": "abcd1",
"user": "dylon"
},
"headers": {
"Test-Header": "only-for-test",
"with": "more"
},
"origin": "127.0.0.1",
"url": "http://127.0.0.1/get?test=abcd1&user=dylon"
}
# 拒绝请求并重写状态码和响应头
curl -XGET '127.0.0.1:9080/get?test=abcd&user=alice' \
--header 'test-header: only-for-test'
HTTP/1.1 302 Moved Temporarily
Date: Mon, 20 Dec 2021 09:37:35 GMT
Content-Type: text/html
Content-Length: 142
Connection: keep-alive
Location: http://example.com/auth
Server: APISIX/2.11.0
# 拒绝请求并返回自定义响应头
curl -XGET '127.0.0.1:9080/get?test=abcd&user=bob' \
--header 'test-header: only-for-test'
HTTP/1.1 403 Forbidden
Date: Mon, 20 Dec 2021 09:38:27 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 150
Connection: keep-alive
abce: test
test: abcd
Server: APISIX/2.11.0
# 拒绝请求并返回自定义响应(字符串)curl -XGET '127.0.0.1:9080/get?test=abcd&user=carla' \
--header 'test-header: only-for-test'
HTTP/1.1 403 Forbidden
Date: Mon, 20 Dec 2021 09:38:58 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/2.11.0
Give you a string reason
# 拒绝请求并返回自定义响应(JSON)curl -XGET '127.0.0.1:9080/get?test=abcd&user=dylon' \
--header 'test-header: only-for-test'
HTTP/1.1 403 Forbidden
Date: Mon, 20 Dec 2021 09:42:12 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/2.11.0
{"code":40001,"desc":"Give you a object reason"}
补充:敞开插件
得益于 Apache APISIX 的动态化个性,只须要移除路由配置中 opa
插件相干配置并保留,即可敞开路由上的 OPA 插件。
总结
本文为大家形容了 Apache APISIX 和 Open Policy Agent 对接的具体操作步骤,心愿通过本文能够让大家对于在 Apache APISIX 中应用 Open Policy Agent 有了更清晰的了解,不便后续进行上手实操。
Apache APISIX 不仅致力于放弃本身的高性能,也始终非常重视开源生态的建设。目前 Apache APISIX 曾经领有了 10+ 个认证受权相干的插件,反对与业界支流的认证受权服务对接。
如果你有对接其余认证受权的需要,无妨拜访 Apache APISIX 的 GitHub,通过 issue 留下你的倡议;或订阅 Apache APISIX 的邮件列表,通过邮件表白你的想法。