Skip to content

Commit

Permalink
fix:fix bug in ext-auth wasm plugin (alibaba#1152)
Browse files Browse the repository at this point in the history
  • Loading branch information
hanxiantao authored Aug 5, 2024
1 parent cc74c0d commit 08c64ed
Show file tree
Hide file tree
Showing 8 changed files with 278 additions and 125 deletions.
1 change: 1 addition & 0 deletions plugins/wasm-go/extensions/ext-auth/.buildrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
EXTRA_TAGS=proxy_wasm_version_0_2_100
165 changes: 136 additions & 29 deletions plugins/wasm-go/extensions/ext-auth/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
# 功能说明
---
title: 外部认证
keywords: [higress, auth]
description: Ext 认证插件实现了调用外部授权服务进行认证鉴权的功能。
---

## 功能说明

`ext-auth` 插件实现了向外部授权服务发送鉴权请求,以检查客户端请求是否得到授权。该插件实现时参考了Envoy原生的[ext_authz filter](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/ext_authz_filter),实现了原生filter中对接HTTP服务的部分能力



# 配置字段
## 配置字段

| 名称 | 数据类型 | 必填 | 默认值 | 描述 |
| ------------------------------- | -------- | ---- | ------ |------------------------------------------------------------------------------------------------------------------------------------------------------------|
Expand All @@ -17,29 +23,30 @@

| 名称 | 数据类型 | 必填 | 默认值 | 描述 |
| ------------------------ | -------- | ---- | ------ | ------------------------------------- |
| `endpoint_mode` | string || envoy | `envoy` , `forward_auth` 中选填一项 |
| `endpoint` | object || - | 发送鉴权请求的 HTTP 服务信息 |
| `timeout` | int || 200 | `ext-auth` 服务连接超时时间,单位毫秒 |
| `timeout` | int || 1000 | `ext-auth` 服务连接超时时间,单位毫秒 |
| `authorization_request` | object || - | 发送鉴权请求配置 |
| `authorization_response` | object || - | 处理鉴权响应配置 |
| `authorization_response` | object || - | 处理鉴权响应配置 |

`endpoint`中每一项的配置字段说明

| 名称 | 数据类型 | 必填 | 默认值 | 描述 |
| ---------------- | -------- | ---- | ------ | --------------------------------------------------- |
| `service_source` | string || - | 类型为固定 ip 或者 dns,输入授权服务的注册来源 |
| `service_name` | string || - | 输入授权服务的注册名称 |
| `service_port` | string || - | 输入授权服务的服务端口 |
| `service_domain` | string || - | 当类型为dns时必须填写,输入 `ext-auth` 服务的domain |
| `request_method` | string || GET | 客户端向授权服务发送请求的HTTP Method |
| `path` | string || - | 输入授权服务的请求路径 |
| 名称 | 数据类型 | 必填 | 默认值 | 描述 |
| -------- | -------- | -- | ------ |-----------------------------------------------------------------------------------------|
| `service_name` | string | 必填 | - | 输入授权服务名称,带服务类型的完整 FQDN 名称,例如 `ext-auth.dns``ext-auth.my-ns.svc.cluster.local` |
| `service_port` | int || 80 | 输入授权服务的服务端口 |
| `path_prefix` | string | `endpoint_mode``envoy`时必填 | | `endpoint_mode``envoy` 时,客户端向授权服务发送请求的请求路径前缀 |
| `request_method` | string || GET | `endpoint_mode``forward_auth` 时,客户端向授权服务发送请求的HTTP Method |
| `path` | string | `endpoint_mode``forward_auth`时必填 | - | `endpoint_mode``forward_auth` 时,客户端向授权服务发送请求的请求路径 |

`authorization_request`中每一项的配置字段说明

| 名称 | 数据类型 | 必填 | 默认值 | 描述 |
| ------------------- | ---------------------- | ---- | ------ | ------------------------------------------------------------ |
| `allowed_headers` | array of StringMatcher || - | 当设置后,具有相应匹配项的客户端请求头将添加到授权服务请求中的请求头中。除了用户自定义的头部匹配规则外,授权服务请求中会自动包含`Host`, `Method`, `Path`, `Content-Length``Authorization`这几个关键的HTTP头 |
| `headers_to_add` | `map[string]string` || - | 设置将包含在授权服务请求中的请求头列表。请注意,同名的客户端请求头将被覆盖 |
| `with_request_body` | bool || false | 缓冲客户端请求体,并将其发送至鉴权请求中(HTTP Method为GET、OPTIONS、HEAD请求时不生效) |
| 名称 | 数据类型 | 必填 | 默认值 | 描述 |
| ------------------------ | ---------------------- | ---- | ------ | ------------------------------------------------------------ |
| `allowed_headers` | array of StringMatcher || - | 当设置后,具有相应匹配项的客户端请求头将添加到授权服务请求中的请求头中。除了用户自定义的头部匹配规则外,授权服务请求中会自动包含`Host`, `Method`, `Path`, `Content-Length``Authorization`这几个关键的HTTP头 |
| `headers_to_add` | `map[string]string` || - | 设置将包含在授权服务请求中的请求头列表。请注意,同名的客户端请求头将被覆盖 |
| `with_request_body` | bool || false | 缓冲客户端请求体,并将其发送至鉴权请求中(HTTP Method为GET、OPTIONS、HEAD请求时不生效) |
| `max_request_body_bytes` | int || 10MB | 设置在内存中保存客户端请求体的最大尺寸。当客户端请求体达到在此字段中设置的数值时,将会返回HTTP 413状态码,并且不会启动授权过程。注意,这个设置会优先于 `failure_mode_allow` 的配置 |

`authorization_response`中每一项的配置字段说明

Expand All @@ -60,24 +67,126 @@



# 配置示例
## 配置示例

下面假设 `ext-auth` 服务在Kubernetes中serviceName为 `ext-auth`,端口 `8090`,路径为 `/auth`,命名空间为 `backend`

## 示例1
支持两种 `endpoint_mode`

- `endpoint_mode``envoy` 时,鉴权请求会使用原始请求的HTTP Method,和配置的 `path_prefix` 作为请求路径前缀拼接上原始的请求路径
- `endpoint_mode``forward_auth` 时,鉴权请求会使用配置的 `request_method` 作为HTTP Method,和配置的 `path` 作为请求路径

### endpoint_mode为envoy时

#### 示例1

`ext-auth` 插件的配置:

```yaml
http_service:
endpoint_mode: envoy
endpoint:
service_name: ext-auth.backend.svc.cluster.local
service_port: 8090
path_prefix: /auth
timeout: 1000
```
使用如下请求网关,当开启 `ext-auth` 插件后:

```shell
curl -X POST http://localhost:8082/users?apikey=9a342114-ba8a-11ec-b1bf-00163e1250b5 -X GET -H "foo: bar" -H "Authorization: xxx"
```

**请求 `ext-auth` 服务成功:**

`ext-auth` 服务将接收到如下的鉴权请求:

```
POST /auth/users?apikey=9a342114-ba8a-11ec-b1bf-00163e1250b5 HTTP/1.1
Host: ext-auth
Authorization: xxx
Content-Length: 0
```
**请求 `ext-auth` 服务失败:**
当调用 `ext-auth` 服务响应为 5xx 时,客户端将接收到HTTP响应码403和 `ext-auth` 服务返回的全量响应头
假如 `ext-auth` 服务返回了 `x-auth-version: 1.0` 和 `x-auth-failed: true` 的响应头,会传递给客户端
```
HTTP/1.1 403 Forbidden
x-auth-version: 1.0
x-auth-failed: true
date: Tue, 16 Jul 2024 00:19:41 GMT
server: istio-envoy
content-length: 0
```
当 `ext-auth` 无法访问或状态码为 5xx 时,将以 `status_on_error` 配置的状态码拒绝客户端请求
当 `ext-auth` 服务返回其他 HTTP 状态码时,将以返回的状态码拒绝客户端请求。如果配置了 `allowed_client_headers`,具有相应匹配项的响应头将添加到客户端的响应中
#### 示例2
`ext-auth` 插件的配置:
```yaml
http_service:
authorization_request:
allowed_headers:
- exact: x-auth-version
headers_to_add:
x-envoy-header: true
authorization_response:
allowed_upstream_headers:
- exact: x-user-id
- exact: x-auth-version
endpoint_mode: envoy
endpoint:
service_name: ext-auth
namespace: backend
service_name: ext-auth.backend.svc.cluster.local
service_port: 8090
path_prefix: /auth
timeout: 1000
```

使用如下请求网关,当开启 `ext-auth` 插件后:

```shell
curl -X POST http://localhost:8082/users?apikey=9a342114-ba8a-11ec-b1bf-00163e1250b5 -X GET -H "foo: bar" -H "Authorization: xxx"
```

`ext-auth` 服务将接收到如下的鉴权请求:

```
POST /auth/users?apikey=9a342114-ba8a-11ec-b1bf-00163e1250b5 HTTP/1.1
Host: ext-auth
Authorization: xxx
X-Auth-Version: 1.0
x-envoy-header: true
Content-Length: 0
```

`ext-auth` 服务返回响应头中如果包含 `x-user-id``x-auth-version`,网关调用upstream时的请求中会带上这两个请求头



### endpoint_mode为forward_auth时

#### 示例1

`ext-auth` 插件的配置:

```yaml
http_service:
endpoint_mode: forward_auth
endpoint:
service_name: ext-auth.backend.svc.cluster.local
service_port: 8090
service_source: k8s
path: /auth
request_method: POST
timeout: 500
timeout: 1000
```
使用如下请求网关,当开启 `ext-auth` 插件后:
Expand Down Expand Up @@ -116,8 +225,7 @@ content-length: 0
当 `ext-auth` 服务返回其他 HTTP 状态码时,将以返回的状态码拒绝客户端请求。如果配置了 `allowed_client_headers`,具有相应匹配项的响应头将添加到客户端的响应中
## 示例2
#### 示例2
`ext-auth` 插件的配置:
Expand All @@ -132,14 +240,13 @@ http_service:
allowed_upstream_headers:
- exact: x-user-id
- exact: x-auth-version
endpoint_mode: forward_auth
endpoint:
service_name: ext-auth
namespace: backend
service_name: ext-auth.backend.svc.cluster.local
service_port: 8090
service_source: k8s
path: /auth
request_method: POST
timeout: 500
timeout: 1000
```

使用如下请求网关,当开启 `ext-auth` 插件后:
Expand Down
Loading

0 comments on commit 08c64ed

Please sign in to comment.