外部授權 (ext_authz
) 過濾器
外部授權沙箱示範了 Envoy 的 ext_authz 過濾器 功能,可將通過 Envoy 的傳入請求的授權委派給外部服務。
雖然 ext_authz 也可用作網路過濾器,但此沙箱僅限於展示 ext_authz HTTP 過濾器,該過濾器支援呼叫 HTTP 或 gRPC 服務。
此沙箱的設定與前端代理部署非常相似,但是對代理後面上游服務的呼叫將由外部 HTTP 或 gRPC 服務檢查。在此沙箱中,對於每個授權的呼叫,外部授權服務都會將額外的 x-current-user
標頭項目新增到要轉發到上游服務的原始請求標頭中。
步驟 1:啟動所有容器
變更為 examples/ext_authz
目錄。
若要建置此沙箱範例並啟動範例服務,請執行以下命令
$ pwd
envoy/examples/ext_authz
$ docker compose pull
$ docker compose up --build -d
$ docker compose ps
Name Command State Ports
--------------------------------------------------------------------------------------------------------------------
ext_authz_ext_authz-grpc-service_1 /app/server -users /etc/us Up
ext_authz_ext_authz-http-service_1 docker-entrypoint.sh node Up
ext_authz_front-envoy_1 /docker-entrypoint.sh /bin Up 10000/tcp, 0.0.0.0:8000->8000/tcp
ext_authz_upstream-service_1 python3 /code/service.py Up (healthy)
注意
此沙箱具有由 FRONT_ENVOY_YAML
環境變數控制的多個設定,該變數指向要使用的有效 Envoy 配置。FRONT_ENVOY_YAML
的預設值可以在 .env
檔案中定義,或在執行 docker compose up
命令時內嵌提供。
如需更多資訊,請參閱 Compose 文件中的環境變數。
預設情況下,FRONT_ENVOY_YAML
指向 config/grpc-service/v3.yaml
檔案,該檔案使用 ext_authz HTTP 過濾器和 gRPC 服務 V3
啟動前端 Envoy (這由 transport_api_version 欄位 指定)。
FRONT_ENVOY_YAML
的可能值可以在 config
目錄中找到。
例如,若要使用帶有 HTTP 服務的 ext_authz HTTP 過濾器執行 Envoy,則會是
$ pwd
envoy/examples/ext_authz
$ docker compose pull
$ # Tearing down the currently running setup
$ docker compose down
$ FRONT_ENVOY_YAML=config/http-service.yaml docker compose up --build -d
$ # Or you can update the .env file with the above FRONT_ENVOY_YAML value, so you don't have to specify it when running the "up" command.
步驟 4:存取前端 Envoy 後面的上游服務
您現在可以嘗試通過前端 Envoy 向上游服務發送請求,如下所示
$ curl -v localhost:8000/service
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /service HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 403 Forbidden
< date: Fri, 19 Jun 2020 15:02:24 GMT
< server: envoy
< content-length: 0
如所觀察,請求失敗,並顯示 403 Forbidden
狀態碼。發生這種情況是因為 Envoy 採用的 ext_authz 過濾器拒絕了呼叫。若要讓請求到達上游服務,您需要通過 Authorization
標頭提供 Bearer
權杖。
注意
完整的用戶列表在 auth/users.json
檔案中定義。例如,以下範例中使用的 token1
對應於 user1
。
成功的請求範例可以觀察如下
$ curl -v -H "Authorization: Bearer token1" localhost:8000/service
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /service HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.58.0
> Accept: */*
> Authorization: Bearer token1
>
< HTTP/1.1 200 OK
< content-type: text/html; charset=utf-8
< content-length: 24
< server: envoy
< date: Fri, 19 Jun 2020 15:04:29 GMT
< x-envoy-upstream-service-time: 2
<
* Connection #0 to host localhost left intact
Hello user1 from behind Envoy!
我們還可以採用 Open Policy Agent 伺服器 (啟用 envoy_ext_authz_grpc 外掛程式) 作為授權伺服器。若要執行此範例
$ pwd
envoy/examples/ext_authz
$ docker compose pull
$ # Tearing down the currently running setup
$ docker compose down
$ FRONT_ENVOY_YAML=config/opa-service/v3.yaml docker compose up --build -d
向 (通過前端 Envoy) 的上游服務發送請求會產生
$ curl localhost:8000/service --verbose
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8000 (#0)
> GET /service HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< content-type: text/html; charset=utf-8
< content-length: 28
< server: envoy
< date: Thu, 02 Jul 2020 06:29:58 GMT
< x-envoy-upstream-service-time: 2
<
* Connection #0 to host localhost left intact
Hello OPA from behind Envoy!
從日誌中,我們可以觀察到來自 Open Policy Agent 伺服器的策略決策訊息 (對於上述針對 config/opa-service/policy.rego
中定義的策略的請求)
$ docker compose logs ext_authz-opa-service | grep decision_id -A 30
ext_authz-opa-service_1 | "decision_id": "8143ca68-42d8-43e6-ade6-d1169bf69110",
ext_authz-opa-service_1 | "input": {
ext_authz-opa-service_1 | "attributes": {
ext_authz-opa-service_1 | "destination": {
ext_authz-opa-service_1 | "address": {
ext_authz-opa-service_1 | "Address": {
ext_authz-opa-service_1 | "SocketAddress": {
ext_authz-opa-service_1 | "PortSpecifier": {
ext_authz-opa-service_1 | "PortValue": 8000
ext_authz-opa-service_1 | },
ext_authz-opa-service_1 | "address": "172.28.0.6"
ext_authz-opa-service_1 | }
ext_authz-opa-service_1 | }
ext_authz-opa-service_1 | }
ext_authz-opa-service_1 | },
ext_authz-opa-service_1 | "metadata_context": {},
ext_authz-opa-service_1 | "request": {
ext_authz-opa-service_1 | "http": {
ext_authz-opa-service_1 | "headers": {
ext_authz-opa-service_1 | ":authority": "localhost:8000",
ext_authz-opa-service_1 | ":method": "GET",
ext_authz-opa-service_1 | ":path": "/service",
ext_authz-opa-service_1 | "accept": "*/*",
ext_authz-opa-service_1 | "user-agent": "curl/7.64.1",
ext_authz-opa-service_1 | "x-forwarded-proto": "http",
ext_authz-opa-service_1 | "x-request-id": "b77919c0-f1d4-4b06-b444-5a8b32d5daf4"
ext_authz-opa-service_1 | },
ext_authz-opa-service_1 | "host": "localhost:8000",
ext_authz-opa-service_1 | "id": "16617514055874272263",
ext_authz-opa-service_1 | "method": "GET",
ext_authz-opa-service_1 | "path": "/service",
嘗試發送方法不是 GET
的請求會導致拒絕
$ curl -X POST localhost:8000/service --verbose
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8000 (#0)
> PUT /service HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 403 Forbidden
< date: Thu, 02 Jul 2020 06:46:13 GMT
< server: envoy
< content-length: 0
另請參閱
- ext_authz 過濾器
了解有關使用 Envoy 的
ext_authz
過濾器的更多資訊。- Open Policy Agent
適用於雲原生環境的基於策略的控制。
- envoy_ext_authz_grpc
Open Policy Agent Envoy 外掛程式。
- Compose 文件中的環境變數.
有關使用 Docker Compose 環境變數的更多資訊。