mirror of
https://github.com/alibaba/higress.git
synced 2026-03-01 23:20:52 +08:00
update plugins doc (#1305)
This commit is contained in:
@@ -1,13 +1,32 @@
|
||||
# 功能说明
|
||||
---
|
||||
title: HMAC 认证
|
||||
keywords: [higress,hmac auth]
|
||||
description: HMAC 认证插件配置参考
|
||||
---
|
||||
|
||||
## 功能说明
|
||||
`hmac-auth`插件实现了基于 HMAC 算法为 HTTP 请求生成不可伪造的签名,并基于签名实现身份认证和鉴权
|
||||
|
||||
# 配置字段
|
||||
## 运行属性
|
||||
|
||||
插件执行阶段:`认证阶段`
|
||||
插件执行优先级:`330`
|
||||
|
||||
## 配置字段
|
||||
|
||||
**注意:**
|
||||
|
||||
- 在一个规则里,鉴权配置和认证配置不可同时存在
|
||||
- 对于通过认证鉴权的请求,请求的header会被添加一个`X-Mse-Consumer`字段,用以标识调用者的名称。
|
||||
|
||||
### 认证配置
|
||||
|
||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||
| ------------- | --------------- | -------- | ------ | ------------------------------------------------------------------------------------------------------------------- |
|
||||
| `global_auth` | bool | 选填(**仅实例级别配置**) | - | 只能在实例级别配置,若配置为true,则全局生效认证机制; 若配置为false,则只对做了配置的域名和路由生效认证机制,若不配置则仅当没有域名和路由配置时全局生效(兼容老用户使用习惯)。 |
|
||||
| `consumers` | array of object | 必填 | - | 配置服务的调用者,用于对请求进行认证 |
|
||||
| `date_offset` | number | 选填 | - | 配置允许的客户端最大时间偏移,单位为秒,根据请求头`Date`解析客户端 UTC 时间,可用于避免请求重放;未配置时,不做校验 |
|
||||
| `_rules_` | array of object | 选填 | - | 配置特定路由或域名的访问权限列表,用于对请求进行鉴权 |
|
||||
|
||||
|
||||
`consumers`中每一项的配置字段说明如下:
|
||||
|
||||
@@ -17,24 +36,21 @@
|
||||
| `secret` | string | 必填 | - | 配置用于生成签名的secret |
|
||||
| `name` | string | 必填 | - | 配置该consumer的名称 |
|
||||
|
||||
`_rules_` 中每一项的配置字段说明如下:
|
||||
### 鉴权配置(非必需)
|
||||
|
||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||
| ---------------- | --------------- | ------------------------------------------------- | ------ | -------------------------------------------------- |
|
||||
| `_match_route_` | array of string | 选填,`_match_route_`,`_match_domain_`中选填一项 | - | 配置要匹配的路由名称 |
|
||||
| `_match_domain_` | array of string | 选填,`_match_route_`,`_match_domain_`中选填一项 | - | 配置要匹配的域名 |
|
||||
| `allow` | array of string | 必填 | - | 对于符合匹配条件的请求,配置允许访问的consumer名称 |
|
||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||
| ----------- | --------------- | ------------------------------------------- | ------ | ----------------------------------------------------------- |
|
||||
| `allow` | array of string | 选填(**非实例级别配置**) | - | 只能在路由或域名等细粒度规则上配置,对于符合匹配条件的请求,配置允许访问的 consumer,从而实现细粒度的权限控制 |
|
||||
|
||||
**注意:**
|
||||
- 若不配置`_rules_`字段,则默认对当前网关实例的所有路由开启认证;
|
||||
- 对于通过认证鉴权的请求,请求的header会被添加一个`X-Mse-Consumer`字段,用以标识调用者的名称。
|
||||
|
||||
# 配置示例
|
||||
## 配置示例
|
||||
|
||||
以下配置将对网关特定路由或域名开启 Hmac Auth 认证和鉴权,注意`key`字段不能重复
|
||||
### 全局配置认证和路由粒度进行鉴权
|
||||
|
||||
在实例级别做如下插件配置, 注意`key`字段不能重复:
|
||||
|
||||
## 对特定路由或域名开启
|
||||
```yaml
|
||||
global_auth: false
|
||||
consumers:
|
||||
- key: appKey-example-1
|
||||
secret: appSecret-example-1
|
||||
@@ -42,34 +58,33 @@ consumers:
|
||||
- key: appKey-example-2
|
||||
secret: appSecret-example-2
|
||||
name: consumer-2
|
||||
# 使用 _rules_ 字段进行细粒度规则配置
|
||||
_rules_:
|
||||
# 规则一:按路由名称匹配生效
|
||||
- _match_route_:
|
||||
- route-a
|
||||
- route-b
|
||||
allow:
|
||||
- consumer-1
|
||||
# 规则二:按域名匹配生效
|
||||
- _match_domain_:
|
||||
- "*.example.com"
|
||||
- test.com
|
||||
allow:
|
||||
- consumer-2
|
||||
```
|
||||
每条匹配规则下的`allow`字段用于指定该匹配条件下允许访问的调用者列表;
|
||||
|
||||
此例 `_match_route_` 中指定的 `route-a` 和 `route-b` 即在创建网关路由时填写的路由名称,当匹配到这两个路由时,将允许`name`为`consumer-1`的调用者访问,其他调用者不允许访问;
|
||||
|
||||
此例 `_match_domain_` 中指定的 `*.example.com` 和 `test.com` 用于匹配请求的域名,当发现域名匹配时,将允许`name`为`consumer-2`的调用者访问,其他调用者不允许访问;
|
||||
|
||||
认证成功后,请求的header中会被添加一个`X-Mse-Consumer`字段,其值为调用方的名称,例如`consumer-1`。
|
||||
|
||||
## 网关实例级别开启
|
||||
|
||||
以下配置将对网关实例级别开启 Hamc Auth 认证
|
||||
route-a和route-b两个路由做如下插件配置:
|
||||
|
||||
```yaml
|
||||
allow:
|
||||
- consumer1
|
||||
```
|
||||
|
||||
在*.example.com和test.com两个域名做如下插件配置:
|
||||
|
||||
```yaml
|
||||
allow:
|
||||
- consumer2
|
||||
```
|
||||
|
||||
若是在控制台进行配置,此例指定的route-a和route-b即在创建网关路由时填写的路由名称,当匹配到这两个路由时,将允许name为consumer1的调用者访问,其他调用者不允许访问。
|
||||
|
||||
此例指定的*.example.com和test.com用于匹配请求的域名,当发现域名匹配时,将允许name为consumer2的调用者访问,其他调用者不被允许访问。
|
||||
|
||||
|
||||
### 网关实例级别开启
|
||||
|
||||
以下配置将对网关实例级别开启 Hamc Auth 认证,所有请求均需要经过认证后才能访问。
|
||||
|
||||
```yaml
|
||||
global_auth: true
|
||||
consumers:
|
||||
- key: appKey-example-1
|
||||
secret: appSecret-example-1
|
||||
@@ -80,18 +95,18 @@ consumers:
|
||||
```
|
||||
|
||||
|
||||
# 签名机制说明
|
||||
## 签名机制说明
|
||||
|
||||
## 配置准备
|
||||
### 配置准备
|
||||
|
||||
如上指引,在插件配置中配置生成和验证签名需要用的凭证配置
|
||||
|
||||
- key: 用于请求头 `x-ca-key` 中设置
|
||||
- secret: 用于生成请求签名
|
||||
|
||||
## 客户端签名生成方式
|
||||
### 客户端签名生成方式
|
||||
|
||||
### 流程简介
|
||||
#### 流程简介
|
||||
|
||||
客户端生成签名一共分三步处理:
|
||||
|
||||
@@ -104,7 +119,7 @@ consumers:
|
||||
如下图所示:
|
||||

|
||||
|
||||
### 签名串提取流程
|
||||
#### 签名串提取流程
|
||||
|
||||
客户端需要从Http请求中提取出关键数据,组合成一个签名串,生成的签名串的格式如下:
|
||||
|
||||
@@ -160,7 +175,7 @@ Path + "?" + Key1 + "=" + Value1 + "&" + Key2 + "=" + Value2 + ... "&" + KeyN +
|
||||
|
||||
4. Query和Form存在数组参数时(key相同,value不同的参数) ,取第一个Value参与签名计算
|
||||
|
||||
### 签名串提取示例
|
||||
#### 签名串提取示例
|
||||
|
||||
初始的HTTP请求:
|
||||
```text
|
||||
@@ -190,7 +205,7 @@ x-ca-timestamp:1525872629832
|
||||
/http2test/test?param1=test&password=123456789&username=xiaoming
|
||||
```
|
||||
|
||||
### 签名计算流程
|
||||
#### 签名计算流程
|
||||
|
||||
客户端从HTTP请求中提取出关键数据组装成签名串后,需要对签名串进行加密及编码处理,形成最终的签名
|
||||
|
||||
@@ -206,7 +221,7 @@ String sign = Base64.encodeBase64String(result);
|
||||
|
||||
总结一下,就是将 `stringToSign` 使用UTF-8解码后得到Byte数组,然后使用加密算法对Byte数组进行加密,然后使用Base64算法进行编码,形成最终的签名。
|
||||
|
||||
### 添加签名流程
|
||||
#### 添加签名流程
|
||||
|
||||
客户端需要将以下四个Header放在HTTP请求中传输给API网关,进行签名校验:
|
||||
|
||||
@@ -238,9 +253,9 @@ content-length:33
|
||||
username=xiaoming&password=123456789
|
||||
```
|
||||
|
||||
## 服务端签名验证方式
|
||||
### 服务端签名验证方式
|
||||
|
||||
### 流程简介
|
||||
#### 流程简介
|
||||
|
||||
服务器验证客户端签名一共分四步处理:
|
||||
|
||||
@@ -256,7 +271,7 @@ username=xiaoming&password=123456789
|
||||

|
||||
|
||||
|
||||
## 签名排错方法
|
||||
### 签名排错方法
|
||||
|
||||
网关签名校验失败时,会将服务端的签名串(StringToSign)放到HTTP Response的Header中返回到客户端,Key为:X-Ca-Error-Message,用户只需要将本地计算的签名串(StringToSign)与服务端返回的签名串进行对比即可找到问题;
|
||||
|
||||
@@ -269,7 +284,7 @@ X-Ca-Error-Message: Server StringToSign:`GET#application/json##application/json
|
||||
|
||||
```
|
||||
|
||||
# 相关错误码
|
||||
## 相关错误码
|
||||
|
||||
| HTTP 状态码 | 出错信息 | 原因说明 |
|
||||
| ----------- | ---------------------- | -------------------------------------------------------------------------------- |
|
||||
@@ -281,5 +296,3 @@ X-Ca-Error-Message: Server StringToSign:`GET#application/json##application/json
|
||||
| 413 | Request Body Too Large | 请求 Body 超过限制大小:32 MB |
|
||||
| 413 | Payload Too Large | 请求 Body 超过全局配置 DownstreamConnectionBufferLimits |
|
||||
| 403 | Unauthorized Consumer | 请求的调用方无访问权限 |
|
||||
|
||||
|
||||
|
||||
@@ -1,76 +1,71 @@
|
||||
# Function Description
|
||||
The `hmac-auth` plugin implements the generation of tamper-proof signatures for HTTP requests based on HMAC algorithm, and uses the signature for identity authentication and authorization.
|
||||
---
|
||||
title: HMAC Authentication
|
||||
keywords: [higress,hmac auth]
|
||||
description: HMAC Authentication plugin configuration reference
|
||||
---
|
||||
## Function Description
|
||||
The `hmac-auth` plugin implements the generation of tamper-proof signatures for HTTP requests based on the HMAC algorithm, and performs authentication and authorization based on the signature.
|
||||
|
||||
# Configuration Fields
|
||||
## Running Attributes
|
||||
Plugin execution phase: `Authentication phase`
|
||||
Plugin execution priority: `330`
|
||||
|
||||
| Name | Data Type | Required | Default | Description |
|
||||
| ------------- | --------------- | -------------| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `consumers` | array of object | Required | - | Configures the caller of the service to authenticate the request. |
|
||||
| `date_offset` | number | Optional | - | Configures the maximum allowed time deviation of the client, in seconds. It is used to parse the client's UTC time from `the Date` header of the request, and can be used to prevent replay attacks. If not configured, no validation is performed. |
|
||||
| `_rules_` | array of object | Optional | - | Configures the access control list for specific routes or domains, used for authorization of requests. |
|
||||
## Configuration Fields
|
||||
**Note:**
|
||||
- In a rule, authentication and authorization configurations cannot coexist.
|
||||
- For requests that pass authentication and authorization, the request header will be added with an `X-Mse-Consumer` field to identify the caller's name.
|
||||
|
||||
The configuration fields for each item in `consumers` are as follows :
|
||||
### Authentication Configuration
|
||||
| Name | Data Type | Requirement | Default Value | Description |
|
||||
| ------------- | ---------------- | ------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| `global_auth` | bool | Optional (**Instance level configuration only**) | - | Can only be configured at the instance level. If set to true, it acts globally; if false, only applies to configured domains and routes. If not configured, it will apply globally only when there are no domain and route configurations (to accommodate old user habits). |
|
||||
| `consumers` | array of object | Mandatory | - | Configures the callers of the service for request authentication. |
|
||||
| `date_offset` | number | Optional | - | Configures the maximum allowed client time offset, in seconds; parsed based on the request header `Date`; can be used to prevent request replay; no validation is performed if not configured. |
|
||||
|
||||
| Name | Data Type| Required | Default| Description |
|
||||
| -------- | -------- | ------------ | ------ | ----------------------------------------------------------------------- |
|
||||
| `key` | string | Required | - | Configures the key extracted from the `x-ca-key` header of the request. |
|
||||
| `secret` | string | Required | - | Configures the secret used to generate the signature. |
|
||||
| `name` | string | Required | - | Configures the name of the consumer. |
|
||||
The configuration fields for each item in `consumers` are as follows:
|
||||
| Name | Data Type | Requirement | Default Value | Description |
|
||||
| -------- | --------- | ----------- | ------------- | ------------------------------------------- |
|
||||
| `key` | string | Mandatory | - | Configures the key extracted from the `x-ca-key` header of the request. |
|
||||
| `secret` | string | Mandatory | - | Configures the secret used to generate the signature. |
|
||||
| `name` | string | Mandatory | - | Configures the name of the consumer. |
|
||||
|
||||
The configuration fields for each item in `_rules_` are as follows:
|
||||
### Authorization Configuration (Optional)
|
||||
| Name | Data Type | Requirement | Default Value | Description |
|
||||
| ----------- | ---------------- | --------------------------------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `allow` | array of string | Optional (**Non-instance level configuration**) | - | Can only be configured on granular rules such as routes or domains. For requests that match the conditions, configure the allowed consumers to achieve fine-grained permission control. |
|
||||
|
||||
| Name | Data Type | Required | Default | Description |
|
||||
| ---------------- | --------------- | ------------------------------------------------- | ---------------------------- | -------------------------------------------------- |
|
||||
| `_match_route_` | array of string | Optional, either `_match_route_` or `_match_domain_` must be provided | - | Configures the name of the route to match. |
|
||||
| `_match_domain_` | array of string | Optional, either `_match_route_` or `_match_domain_` must be provided | - | Configures the name of the domain to match. |
|
||||
| `allow` | array of string | Required | - | Configures the name of the consumer to allow for requests that match the specified route or domain. |
|
||||
|
||||
**Note:**
|
||||
- If `_rules_` is not configured, authentication is enabled for all routes on the current gateway instance by default ;
|
||||
- For requests that pass authentication and authorization, a `X-Mse-Consumer` header will be added to the request headers to identify the name of the consumer.
|
||||
|
||||
# Configuration Example
|
||||
|
||||
The following configuration enables Hmac Auth authentication and authorization for specific routes or domains on the gateway. Note that the `key` field should not be duplicated.
|
||||
|
||||
## Enabling for specific routes or domains
|
||||
## Configuration Example
|
||||
### Global Configuration Authentication and Route Granular Authorization
|
||||
Configure the following plugin settings at the instance level. Note that the `key` field cannot be duplicated:
|
||||
```yaml
|
||||
consumers:
|
||||
global_auth: false
|
||||
consumers:
|
||||
- key: appKey-example-1
|
||||
secret: appSecret-example-1
|
||||
name: consumer-1
|
||||
- key: appKey-example-2
|
||||
secret: appSecret-example-2
|
||||
name: consumer-2
|
||||
# Configuring Fine-Grained Rules using _rules_ Field
|
||||
_rules_:
|
||||
# Rule 1: Matching by route name.
|
||||
- _match_route_:
|
||||
- route-a
|
||||
- route-b
|
||||
allow:
|
||||
- consumer-1
|
||||
# Rule 2: Applies based on domain name matching.
|
||||
- _match_domain_:
|
||||
- "*.example.com"
|
||||
- test.com
|
||||
allow:
|
||||
- consumer-2
|
||||
```
|
||||
The `allow` field under each matching rule specifies the list of callers allowed to access under that matching condition;
|
||||
|
||||
In this example, `route-a` and `route-b` specified in `_match_route_` are the route names filled in when creating the gateway route. When either of these routes is matched, it will allow access to the caller named `consumer-1`, while denying access to other callers;
|
||||
|
||||
In` _match_domain_`, `*.example.com` and `test.com` are used to match the requested domain name. When a match is found, it will allow access to the caller named `consumer-2`, while denying access to other callers;
|
||||
|
||||
Upon successful authentication, the `X-Mse-Consumer` field will be added to the request header with the value set to the caller's name, such as `consumer-1`.。
|
||||
|
||||
## Enable at the Gateway Instance Level
|
||||
|
||||
The following configuration enables HMAC authentication at the gateway instance level.
|
||||
|
||||
For route-a and route-b, configure the plugin as follows:
|
||||
```yaml
|
||||
consumers:
|
||||
allow:
|
||||
- consumer1
|
||||
```
|
||||
For the two domains *.example.com and test.com, configure as follows:
|
||||
```yaml
|
||||
allow:
|
||||
- consumer2
|
||||
```
|
||||
If configured in the console, the specified route names route-a and route-b correspond to the route names filled in when creating the gateway routes. When matched to these two routes, access will be allowed for the caller named consumer1, while other callers will not be allowed access.
|
||||
|
||||
The specified *.example.com and test.com are used to match the domains of the requests. When a domain match is found, access will be allowed for the caller named consumer2, while other callers will not be allowed access.
|
||||
|
||||
### Gateway Instance Level Activation
|
||||
The following configuration will enable HMAC Auth authentication at the gateway instance level, requiring all requests to undergo authentication before access.
|
||||
```yaml
|
||||
global_auth: true
|
||||
consumers:
|
||||
- key: appKey-example-1
|
||||
secret: appSecret-example-1
|
||||
name: consumer-1
|
||||
@@ -79,34 +74,24 @@ consumers:
|
||||
name: consumer-2
|
||||
```
|
||||
|
||||
## Signature Mechanism Description
|
||||
### Configuration Preparation
|
||||
As mentioned above, configure the credentials required for generating and verifying signatures in the plugin settings.
|
||||
- key: to be set in the request header `x-ca-key`.
|
||||
- secret: used for generating request signatures.
|
||||
|
||||
# Description of Signing Mechanism
|
||||
### Client Signature Generation Process
|
||||
#### Overview
|
||||
The client generates a signature through three main steps:
|
||||
1. Extract key data from the original request to create a string for signing.
|
||||
2. Encrypt the key data signing string using the algorithm and the configured `secret` to obtain the signature.
|
||||
3. Include all relevant headers for the signature into the original HTTP request to form the final HTTP request.
|
||||
|
||||
## Configuration Preparation
|
||||
|
||||
As mentioned in the guide above, configure the credential settings required for generating and validating signatures in the plugin configuration.
|
||||
|
||||
- key: Used for setting in the request header `x-ca-key`.
|
||||
- secret: Used for generating the request signature.
|
||||
|
||||
## Client Signature Generation Method
|
||||
### Overview of the Process
|
||||
|
||||
The process for generating a signature on the client side consists of three steps:
|
||||
|
||||
1. Extracting key data from the original request to obtain a string to be signed.
|
||||
|
||||
2. Using encryption algorithms and the configured `secret` to encrypt the key data signing string and obtain a signature.
|
||||
|
||||
3. Adding all headers related to the signature to the original HTTP request to obtain the final HTTP request.
|
||||
|
||||
As shown below :
|
||||
As shown in the figure below:
|
||||

|
||||
|
||||
### Process for Extracting Signing String
|
||||
|
||||
To generate a signature, the client needs to extract key data from the HTTP request and combine it into a signing string. The format of the generated signing string is as follows:
|
||||
|
||||
#### Signing String Extraction Process
|
||||
The client needs to extract key data from the HTTP request, combine it into a signing string, which has the following format:
|
||||
```text
|
||||
HTTPMethod
|
||||
Accept
|
||||
@@ -116,54 +101,38 @@ Date
|
||||
Headers
|
||||
PathAndParameters
|
||||
```
|
||||
|
||||
The signing string consists of the above 7 fields separated by \n. If Headers is empty, no \n is needed. If other fields are empty, the \n should still be retained. The signature is case-sensitive. Below are the rules for extracting each field:
|
||||
|
||||
- HTTPMethod: The HTTP method used in the request, in all capital letters, such as POST.
|
||||
|
||||
- Accept: The value of the Accept header in the request, which can be empty. It is recommended to explicitly set the Accept header. When Accept is empty, some HTTP clients will set the default value of `*/*`, which may cause signature verification to fail.
|
||||
|
||||
- Content-MD5: The value of the Content-MD5 header in the request, which can be empty. It is only calculated when there is a non-form body in the request. The following is a reference calculation method for Content-MD5 values in :
|
||||
|
||||
|
||||
The seven fields above constitute the entire signing string, separated by newline characters `\n`. If Headers is empty, no newline is needed; other fields should retain `\n` if empty. The signature is case-sensitive. Below are the extraction rules for each field:
|
||||
- HTTPMethod: The HTTP method, all uppercase (e.g., POST).
|
||||
- Accept: The value of the Accept header in the request, can be empty. It is recommended to explicitly set the Accept Header. When Accept is empty, some HTTP clients may set a default value of `*/*`, resulting in a signature verification failure.
|
||||
- Content-MD5: The value of the Content-MD5 header in the request, can be empty. It is calculated only if there is a Body in the request and it is not in Form format. Here’s a reference calculation method for the Content-MD5 value in Java:
|
||||
```java
|
||||
String content-MD5 = Base64.encodeBase64(MD5(bodyStream.getbytes("UTF-8")));
|
||||
String content-MD5 = Base64.encodeBase64(MD5(bodyStream.getBytes("UTF-8")));
|
||||
```
|
||||
|
||||
- Content-Type: The value of the Content-Type header in the request, which can be empty.
|
||||
|
||||
- Date: The value of the Date header in the request. When the` date_offset` configuration is not enabled, it can be empty. Otherwise, it will be used for time offset verification.
|
||||
|
||||
- Headers: Users can select specific headers to participate in the signature. There are the following rules for concatenating the signature string with headers:
|
||||
- The keys of the headers participating in the signature calculation are sorted in alphabetical order and concatenated as follows:
|
||||
- Content-Type: The value of the Content-Type header in the request, can be empty.
|
||||
- Date: The value of the Date header in the request. If the `date_offset` configuration is not turned on, it can be empty; otherwise, it will be used for time offset verification.
|
||||
- Headers: Users can select specific headers to participate in the signature. The rules for concatenating the signing header string are as follows:
|
||||
- The Keys of the headers participating in the signature calculation are concatenated after being sorted lexicographically, as follows:
|
||||
```text
|
||||
HeaderKey1 + ":" + HeaderValue1 + "\n"\+
|
||||
HeaderKey2 + ":" + HeaderValue2 + "\n"\+
|
||||
HeaderKey1 + ":" + HeaderValue1 + "\n" +
|
||||
HeaderKey2 + ":" + HeaderValue2 + "\n" +
|
||||
...
|
||||
HeaderKeyN + ":" + HeaderValueN + "\n"
|
||||
```
|
||||
- If the value of a header is empty, it will participate in the signature with the `HeaderKey+":"+"\n"` only, and the key and english colon should be retained.
|
||||
- The set of keys for all headers participating in the signature is separated by a comma and placed in the `X-Ca-Signature-Headers header`.
|
||||
- If the Value of a certain header is empty, use HeaderKey + ":" + "\n" to participate in the signature, retaining the Key and the colon.
|
||||
- The collection of all participating header Keys is placed in the Header with the key X-Ca-Signature-Headers, separated by commas.
|
||||
- The following headers are not included in the header signature calculation: X-Ca-Signature, X-Ca-Signature-Headers, Accept, Content-MD5, Content-Type, Date.
|
||||
|
||||
- PathAndParameters: This field contains all parameters in the path, query, and form. The specific format is as follows:
|
||||
|
||||
- PathAndParameters: This field includes Path, Query, and all parameters in Form, specifically organized as follows:
|
||||
```text
|
||||
Path + "?" + Key1 + "=" + Value1 + "&" + Key2 + "=" + Value2 + ... "&" + KeyN + "=" + ValueN
|
||||
```
|
||||
Note:
|
||||
1. The Key of Query and Form parameters should be sorted lexicographically before being concatenated as above.
|
||||
2. If Query and Form parameters are empty, just use Path without adding `?`.
|
||||
3. If the Value of parameters is empty, only the Key should be retained in the signature, the equal sign does not need to be added.
|
||||
4. In the case of array parameters (parameters with the same key but different values), only the first Value should be used for signature calculation.
|
||||
|
||||
Notes:
|
||||
1. The keys of the query and form parameter pairs are sorted alphabetically, and the same format as above is used for concatenation.
|
||||
|
||||
2. If there are no query and form parameters, use the path directly without adding `?` .
|
||||
|
||||
3. If the value of a parameter is empty, only the key will be included in the signature. The equal sign should not be included in the signature.
|
||||
|
||||
4. If there are array parameters in the query or form (parameters with the same key but different values), only the first value should be included in the signature calculation.
|
||||
|
||||
### Example of Extracting Signing String
|
||||
|
||||
The initial HTTP request :
|
||||
#### Signing String Extraction Example
|
||||
Initial HTTP request:
|
||||
```text
|
||||
POST /http2test/test?param1=test HTTP/1.1
|
||||
host:api.aliyun.com
|
||||
@@ -177,8 +146,7 @@ x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
|
||||
content-length:33
|
||||
username=xiaoming&password=123456789
|
||||
```
|
||||
|
||||
The correct generated signature string is :
|
||||
The generated correct signing string is:
|
||||
```text
|
||||
POST
|
||||
application/json; charset=utf-8
|
||||
@@ -190,13 +158,10 @@ x-ca-signature-method:HmacSHA256
|
||||
x-ca-timestamp:1525872629832
|
||||
/http2test/test?param1=test&password=123456789&username=xiaoming
|
||||
```
|
||||
#### Signature Calculation Process
|
||||
After the client assembles the key data extracted from the HTTP request into a signing string, it needs to encrypt the signing string and encode it to form the final signature.
|
||||
|
||||
### Signature Calculation Process
|
||||
|
||||
After extracting the key data from the HTTP request and assembling it into a signature string, the client needs to encrypt and encode the signature string to form the final signature.
|
||||
|
||||
The specific encryption format is as follows, where `stringToSign` is the extracted signature string, `secret` is the one filled in the plugin configuration, and `sign` is the final generated signature:
|
||||
|
||||
The specific encryption form is as follows, where `stringToSign` is the extracted signing string, `secret` is the one filled in the plugin configuration, and `sign` is the final generated signature:
|
||||
```java
|
||||
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
|
||||
byte[] secretBytes = secret.getBytes("UTF-8");
|
||||
@@ -204,23 +169,16 @@ hmacSha256.init(new SecretKeySpec(secretBytes, 0, secretBytes.length, "HmacSHA25
|
||||
byte[] result = hmacSha256.doFinal(stringToSign.getBytes("UTF-8"));
|
||||
String sign = Base64.encodeBase64String(result);
|
||||
```
|
||||
To summarize, the `stringToSign` is decoded using UTF-8 to obtain a Byte array, then the encryption algorithm is applied to the Byte array, and finally, the Base64 algorithm is used for encoding, forming the final signature.
|
||||
|
||||
In summary, the `stringToSign` is decoded using UTF-8 to obtain a Byte array. Then, an encryption algorithm is used to encrypt the Byte array, and finally, the Base64 algorithm is used to encode the encrypted data, resulting in the final signature.
|
||||
|
||||
### The Process of Adding a Signature
|
||||
|
||||
The client needs to include the following four headers in the HTTP request to be transmitted to the API gateway for signature verification:
|
||||
|
||||
- x-ca-key: The value is the APP Key and is required.
|
||||
|
||||
- x-ca-signature-method: The signature algorithm, the value can be HmacSHA256 or HmacSHA1, optional. The default value is HmacSHA256.
|
||||
|
||||
- x-ca-signature-headers: The collection of keys for all signature headers, separated by commas. Optional.
|
||||
|
||||
- x-ca-signature: The signature and it is required.
|
||||
|
||||
Here is an example of a complete HTTP request with a signature :
|
||||
#### Adding the Signature Process
|
||||
The client needs to include the following four headers in the HTTP request to transmit to the API gateway for signature verification:
|
||||
- x-ca-key: The APP Key, mandatory.
|
||||
- x-ca-signature-method: The signature algorithm, can be HmacSHA256 or HmacSHA1, optional, default is HmacSHA256.
|
||||
- x-ca-signature-headers: The collection of all signature header Keys, separated by commas, optional.
|
||||
- x-ca-signature: The signature, mandatory.
|
||||
|
||||
Below is an example of the entire HTTP request carrying the signature:
|
||||
```text
|
||||
POST /http2test/test?param1=test HTTP/1.1
|
||||
host:api.aliyun.com
|
||||
@@ -239,48 +197,35 @@ content-length:33
|
||||
username=xiaoming&password=123456789
|
||||
```
|
||||
|
||||
## Server-side Signature Verification Method
|
||||
### Server-side Signature Verification Method
|
||||
#### Overview
|
||||
The server verifies the client signature through four main steps:
|
||||
1. Extract key data from the received request to create a signing string.
|
||||
2. Read the `key` from the received request and query the corresponding `secret`.
|
||||
3. Encrypt the key data signing string using the algorithm and the `secret` to obtain the signature.
|
||||
4. Read the client signature from the received request and compare the server-side signature with the client-side signature for consistency.
|
||||
|
||||
### Overview of the Process
|
||||
|
||||
The server-side signature verification of the client's request involves four steps :
|
||||
|
||||
1. Extract crucial data from the received request to obtain a string for signing.
|
||||
|
||||
2. Retrieve the `key` from the received request and use it to query its corresponding `secret`.
|
||||
|
||||
3. Encrypt the string for signing using the encryption algorithm and `secret`.
|
||||
|
||||
4. Retrieve the client's signature from the received request, and compare the consistency of the server-side signature with the client's signature.
|
||||
|
||||
As shown below :
|
||||
As shown in the figure below:
|
||||

|
||||
|
||||
### Signature Troubleshooting Method
|
||||
When the gateway signature verification fails, the server's signing string (StringToSign) will be returned in the HTTP Response header to the client, with the key: X-Ca-Error-Message. The user only needs to compare the locally computed signing string (StringToSign) with the signing string returned by the server to find the issue.
|
||||
|
||||
## Troubleshooting Signature Errors
|
||||
|
||||
When the gateway signature verification fails, the server-side signing string (StringToSign) will be returned to the client in the HTTP Response Header. The key is X-Ca-Error-Message. Users only need to compare the locally calculated signing string with the server-side signing string returned to locate the problem;
|
||||
|
||||
If the StringToSign on the server side is consistent with that on the client side, please check whether the APP Secret used for signature calculation is correct;
|
||||
|
||||
Because line breaks cannot be represented in HTTP headers, all line breaks in the StringToSign are replaced with #, as shown below:
|
||||
If the StringToSign from the server and the client are consistent, please check whether the APP Secret used for signature calculation is correct.
|
||||
|
||||
Since HTTP headers cannot express line breaks, the line breaks in the StringToSign have been replaced with `#`, as shown below:
|
||||
```text
|
||||
X-Ca-Error-Message: Server StringToSign:`GET#application/json##application/json##X-Ca-Key:200000#X-Ca-Timestamp:1589458000000#/app/v1/config/keys?keys=TEST`
|
||||
|
||||
```
|
||||
|
||||
# Related Error Codes
|
||||
|
||||
| HTTP Status Code | Error Message | Reason |
|
||||
| ----------- | ---------------------- | -------------------------------------------------------------------------------- |
|
||||
| 401 | Invalid Key | The x-ca-key request header is not provided or is invalid. |
|
||||
| 401 | Empty Signature | The x-ca-signature request header does not contain a signature. |
|
||||
| 400 | Invalid Signature | The x-ca-signature request header contains a signature that does not match the server-calculated signature. |
|
||||
| 400 | Invalid Content-MD5 | The content-md5 request header is incorrect. |
|
||||
| 400 | Invalid Date | The time offset calculated based on the date request header exceeds the configured date_offset. |
|
||||
| 413 | Request Body Too Large | The request body exceeds the size limit of 32 MB. |
|
||||
| 413 | Payload Too Large | The request body exceeds the DownstreamConnectionBufferLimits global configuration. |
|
||||
| 403 | Unauthorized Consumer | The requesting party does not have access permission. |
|
||||
|
||||
|
||||
## Related Error Codes
|
||||
| HTTP Status Code | Error Message | Reasoning |
|
||||
| ---------------- | --------------------- | --------------------------------------------- |
|
||||
| 401 | Invalid Key | The request header did not provide x-ca-key, or x-ca-key is invalid. |
|
||||
| 401 | Empty Signature | The request header did not provide the x-ca-signature signing string. |
|
||||
| 400 | Invalid Signature | The x-ca-signature signing string in the request header does not match the signature calculated by the server. |
|
||||
| 400 | Invalid Content-MD5 | The Content-MD5 header in the request is incorrect. |
|
||||
| 400 | Invalid Date | The time offset calculated based on the Date header in the request exceeds the configured date_offset. |
|
||||
| 413 | Request Body Too Large| The request Body exceeds the maximum size of 32 MB. |
|
||||
| 413 | Payload Too Large | The request Body exceeds the global configured DownstreamConnectionBufferLimits. |
|
||||
| 403 | Unauthorized Consumer | The calling party does not have access permissions for the request. |
|
||||
|
||||
Reference in New Issue
Block a user