
# 配置API的JWT认证
JWT（JSON Web Token）是一种轻量级的认证信息格式，广泛应用于API身份验证场景。您可以为API绑定JWT认证策略，利用私钥签发Token并附加在请求中，网关会使用公钥对Token进行鉴权，从而实现API的安全访问控制。API网关支持两种JWKS（JSON Web Key Set）公钥设置方式：
- 在策略中配置远程服务地址，网关会定时访问该地址来获取公钥。
- 在策略中填入固定的公钥。
![](https://support.huaweicloud.com/usermanual-apig/public_sys-resources/note_3.0-zh-cn.png)
如果此策略在当前实例中不支持，可[提交工单](https://support.huaweicloud.com/usermanual-ticket/zh-cn_topic_0127038618.html)升级实例到最新版本。
#### 约束与限制
- 同一个环境中，一个API只能被一个JWT认证策略绑定，但一个JWT认证策略可以绑定多个API。
- 同一个APIG实例内最多可创建5个JWT认证策略。如需调整配额，请[提交工单](https://support.huaweicloud.com/usermanual-ticket/zh-cn_topic_0127038618.html)，申请修改。
- 用户需要通过工具或平台自行生成公私密钥对，在JWT认证策略中配置公钥，并使用对应的私钥生成Token。**请妥善保管私钥避免泄露。**
- 请求中携带的Token应当符合[RFC 7519规范](https://www.rfc-editor.org/rfc/rfc7519)；JWT认证策略配置的公钥应当是符合[RFC 7517规范](https://www.rfc-editor.org/rfc/rfc7517)的JSON格式字符串。
- **由于JWT并不会对数据进行加密，请勿将敏感数据设置在Token中。此外为了避免Token泄露，建议您不要对请求协议为HTTP的API使用JWT认证。**
- Token校验支持的加密算法包含RS256、RS384 、RS512、ES256、ES384和ES512。使用RSA算法时，建议密钥长度大于等于3072位。
- JWKS_URI返回的公钥和固定设置的公钥大小，支持最大为50KB。
- 网关会校验Token中的nbf（生效时间）和exp（过期时间）字段，如果校验失败会拒绝请求。
- 当选择"定时拉取"的公钥设置方式时，必须保证JWKS_URI和APIG实例网络互通。网关内部的定时任务会每隔5min请求JWKS_URI，将返回的响应体作为公钥，并且当次请求的结果会覆盖上次请求的结果。如果要实现公私钥轮转，建议在每次轮换时，留出一段宽限时间，令JWKS_URI返回新公钥和本次轮转被替换的旧公钥，使得新旧私钥签发的Token在这段时间均有效。
- 网关会根据Token和JWKS公钥中的kid进行匹配验签。如果JWKS中只存在一个JWK则kid可以为空，否则不可以为空；JWKS中任意两个JWK的kid不可以相同。如果未设置kid，则公私钥替换后，之前签发的Token无法校验通过。
- 策略和API本身相互独立，只有为API绑定策略后，策略才对API生效。为API绑定策略时需指定发布环境，策略只对指定环境上的API生效。
- API的下线操作不影响策略的绑定关系，再次发布后仍然会带有下线前绑定的策略。
- 如果策略与API有绑定关系，则策略无法执行删除操作。
 
#### 创建JWT认证策略
1. 进入[API网关控制台](https://console.huaweicloud.com/apig2/#/overview)页面。
2. 根据实际业务在左侧导航栏上方选择实例。
3. 在左侧导航栏选择"API管理 \> API策略"。
4. 在"策略管理"页面，单击"创建策略"。
5. 在"选择策略类型"弹窗中，选择"插件策略 \> JWT认证"。
6. 在"创建策略"弹窗中，根据下表参数说明，配置策略信息。 
   表1JWT认证参数说明 
   | 参数             | 说明                                                                                                                                                                                                                                                                                                                                                                                                    |
   |:---|:---|
   | 策略名称           | 填写策略的名称，根据业务规划自定义。建议您按照一定的命名规则填写策略名称，方便您快速识别和查找。                                                                                                                                                                                                                                                                                                                                                      |
   | 策略类型           | 固定为"JWT认证"。                                                                                                                                                                                                                                                                                                                                                                                           |
   | 描述             | 填写策略的描述信息。长度为1\~255个字符。                                                                                                                                                                                                                                                                                                                                                                               |
   | 策略内容           | 策略的配置内容，支持表单配置和脚本配置两种方式。                                                                                                                                                                                                                                                                                                                                                                              |
   | 设置方式           | 获取公钥的方式。 - 定时拉取：网关会每隔5min请求JWKS_URI获取公钥。  - 固定设置：网关会将所填入的JWKS值作为公钥。                                                                                                                                                   |
   | JWKS_URI       | **仅当选择"定时拉取"方式时需配置**。 响应返回JWKS公钥的URI地址，公钥需为遵循[RFC 7517规范](https://www.rfc-editor.org/rfc/rfc7517)的JSON字符串，**需保证JWKS_URI和APIG实例网络互通**。网关内部的定时任务会每隔5min请求JWKS_URI，将返回的响应体作为公钥，并且当次请求的结果会覆盖上次请求的结果。 网关请求URI地址的方法为GET，如果未指定请求协议，则使用HTTPS。返回的JWKS大小最大支持50KB。                                                                                  |
   | JWKS           | **仅当选择"固定设置"方式时需配置**。 验证Token的JWKS公钥，需为遵循[RFC 7517规范](https://www.rfc-editor.org/rfc/rfc7517)的json字符串。最大支持50KB。                                                                                                                                                                                                                                                         |
   | 超时时间           | **仅当选择"定时拉取"方式时需配置**。 网关请求JWKS服务的超时时间（1-60000ms），单位为毫秒。                                                                                                                                                                                                                                                                                                                  |
   | 缓存时间           | **仅当选择"定时拉取"方式时需配置**。 网关会将JWKS服务返回的JWKS进行缓存，允许您自定义缓存时间（600-86400s），单位为秒。                                                                                                                                                                                                                                                                                               |
   | 自定义host头域      | **仅当选择"定时拉取"方式时需配置**。 请求JWKS服务前，允许您自定义请求的host头域，默认将使用请求中原始的host头域。                                                                                                                                                                                                                                                                                                    |
   | Token位置        | Token参数的位置：header，query，cookie。                                                                                                                                                                                                                                                                                                                                                                       |
   | Token名称        | 设置Token参数名称。 - 当Token位置为header时默认值为Authorization，该参数不区分大小写。  - 当Token位置为query时默认值为access_token。  - 当Token位置为cookie时该参数必填，该参数不区分大小写。   |
   | Token前缀        | **仅当Token位置选择"header"时需配置**。 Token字符串将去除该前缀，再用于鉴权。默认值为Bearer。                                                                                                                                                                                                                                                                                                          |
   | Token过期时钟偏移量   | 若token在payload中设置了过期时间（exp），网关会对其进行校验，允许您自定义校验token是否过期的时钟偏移量（0-86400s）。                                                                                                                                                                                                                                                                                                                              |
   | Token透传至后端     | 是否允许将原始token透传至后端。默认关闭开关：不允许。                                                                                                                                                                                                                                                                                                                                                                         |
   | Token不存在时跳过验证  | 当请求未携带Token时，是否允许跳过JWT认证直接访问后端。默认关闭开关：不允许。                                                                                                                                                                                                                                                                                                                                                            |
   | 忽略超期时间校验       | 是否允许网关忽略对Token的超期时间exp字段值的校验。默认关闭开关：不允许。                                                                                                                                                                                                                                                                                                                                                              |
   | Payload传递至后端   | 是否允许将Token解析出的payload传递至后端。默认关闭开关：不允许。                                                                                                                                                                                                                                                                                                                                                                |
   | Payload所在请求头名称 | **仅当"Payload传递至后端"开启开关时需配置**。 将Token解析出的Payload写入到指定名称的请求头。该参数不区分大小写。                                                                                                                                                                                                                                                                                                   |
   | 传递字段值至后端       | 网关将Payload中指定字段（claim）的值，设置到指定名称的请求头中，传递至后端。您可以通过开启或关闭"同名头是否重写"开关来控制是否对同名的请求头进行重写。 - 当"同名头是否重写"开启时，如果存在同名的请求头会将其值覆盖。默认开启，最多支持设置16个字段值传递至后端。  - 当"同名头是否重写"关闭时，会额外追加同名的请求头。                             |
   | 黑名单配置          | 网关将根据黑名单配置，对payload中指定字段的值执行黑名单校验。如果payload中claim对应键值对匹配了黑名单配置中任意一条规则，即claim的值和某条规则中填入的字段值相等，则会拒绝请求。                                                                                                                                                                                                                                                                                                  |
      
   
   
7. 单击"确定"。 
   - 在策略列表中显示已创建的策略，表示策略创建成功。
   
   - 如果您需要复制已创建的策略，请在已创建策略的"操作"列中单击"克隆"配置参数即可。**克隆策略的名称不能与已创建的策略名称重复。**
   
   
   
   
8. 策略创建后，您还需要[为策略绑定API]，才能使策略对API生效。
   
   **策略的绑定、解绑、更新会实时生效，不需要重新发布API。**
   
   
 
#### 脚本配置示例
```
{
    "jwks_service": {
        "uri": "https://example.com",
        "timeout": 5000,
        "ttl": 7200,
        "custom_host": "xxx.xxx"
    },
    "jwks": "{\"keys\":[{\"kty\": \"EC\",\"crv\": \"P-256\",\"x\": \"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\",\"y\": \"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\": \"enc\",\"kid\": \"1\"}] }",
    "token_location": "header",
    "token_name": "Authorization",
    "token_prefix": "Bearer",
    "token_expiration_tolerance": 0,
    "token_pass_through_enabled": true,
    "missing_token_skip_auth_enabled": false,
    "ignore_expiration_validation_enabled": false,
    "claims_to_headers": [
        {
            "claim": "iat",
            "header": "iat_value",
            "is_override": true
        },
        {
            "claim": "sub",
            "header": "sub_value",
            "is_override": false
        }
    ],
    "blacklist": [
        {
            "claim": "iat",
            "value": ""
        },
        {
            "claim": "sub",
            "value": "test"
        }
    ]
}
```
 #### 为策略绑定API
1. 单击策略名称，进入策略详情。
2. 在API列表区域选择环境后，单击"绑定API"。
3. 筛选API分组以及发布环境，勾选所需的API。 
   支持通过API名称或标签筛选API，标签为创建API时定义的标签。
   
   
4. 单击"确定"，绑定完成。 
   - 如果单个API不需要绑定此策略，单击API所在行的"解绑"。
   
   - 如果批量API不需要绑定此策略，则勾选待解绑的API，单击列表上方"解绑"。最多同时解绑1000个API。
   
   
   
   
 
#### 相关文档
- 用户可以通过认证服务器生成JWT，客户端通过在请求中携带Token来访问受保护的资源。网关收到请求后，验证JWT的有效性（签名、有效期等），并可以从Payload中直接提取用户身份和权限信息。操作详情请参考[通过JWT认证策略实现身份认证和密钥轮转](https://support.huaweicloud.com/bestpractice-apig/apig-bp-0082.html)。
- 如果您希望通过API创建JWT认证策略，请参考[创建插件](https://support.huaweicloud.com/api-apig/CreatePlugin.html)。
 
