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 运行 OPAdocker 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 exampleimport input.requestimport data.usersdefault allow = falseallow { # 具备名为 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 TemporarilyDate: Mon, 20 Dec 2021 09:37:35 GMTContent-Type: text/htmlContent-Length: 142Connection: keep-aliveLocation: http://example.com/authServer: 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 ForbiddenDate: Mon, 20 Dec 2021 09:38:27 GMTContent-Type: text/html; charset=utf-8Content-Length: 150Connection: keep-aliveabce: testtest: abcdServer: 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 ForbiddenDate: Mon, 20 Dec 2021 09:38:58 GMTContent-Type: text/plain; charset=utf-8Transfer-Encoding: chunkedConnection: keep-aliveServer: APISIX/2.11.0Give 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 ForbiddenDate: Mon, 20 Dec 2021 09:42:12 GMTContent-Type: application/jsonTransfer-Encoding: chunkedConnection: keep-aliveServer: APISIX/2.11.0{"code":40001,"desc":"Give you a object reason"}补充:敞开插件得益于 Apache APISIX 的动态化个性,只须要移除路由配置中 opa 插件相干配置并保留,即可敞开路由上的 OPA 插件。
...