
# 共享OIDC身份提供商的访问控制
对于共享OpenID Connect（OIDC）身份提供商，IAM要求在委托信任策略中对特定声明（claims）进行显式校验。具体而言，IAM 会对oidc:iss（发行者）和oidc:aud（受众）条件键进行强制校验，这种校验本质上属于访问控制的一部分。虽然我们不会对oidc:sub（主体）条件键进行强制校验，但是强烈推荐您在信任策略中额外增加oidc:sub条件键，在多数场景中它可以有效解决因共享身份提供商所带来的混淆代理问题。
在创建或更新信任委托时，如果信任策略中未对上述关键声明进行限制，则操作将会失败。通过对这些条件键的校验，可以确保只有来自预期组织的身份才能切换信任委托并访问华为云资源，尤其是在多个华为云客户共享同一OIDC身份提供商的场景下，这一点尤为重要。
#### 共享身份提供商
从使用角度可以将OIDC身份提供商分为私有（private）和 共享（shared）：
- 私有OIDC身份提供商可以由单个组织拥有和管理，也可以是 SaaS 提供商的租户，其OIDC颁发者 (Issuer) URL 作为该组织特有的唯一标识符。
- 共享OIDC身份提供商则被多个组织使用，所有使用该共享身份提供商的组织的OIDC颁发者 URL 可能完全相同。
 
下表概述了私有OIDC提供商与共享OIDC提供商之间的关键差异：
表1私有OIDC提供商与共享OIDC提供商之间的关键差异 
| 特征   | 私有OIDC提供商     | 共享OIDC提供商             |
|:---|:---|:---|
| 颁发者  | 组织独有          | 多个组织共享                |
| 租户信息 | 通过唯一的颁发者URL传达 | 通过JWT中的声明 (claims) 传达 |
   
 #### 混淆代理问题
在使用共享OIDC身份提供商时，容易引发一种典型的安全风险------混淆代理问题。其本质在于：云平台中的IAM服务作为**代理方**，根据来自身份提供商的OIDC令牌（ID Token）来决定是否允许用户切换信任委托，但如果该身份提供商是被多个组织共享的，那么不同组织的用户所获取的令牌在表面上可能具有相同的发行者（Issuer）。如果信任策略中仅校验发行者而未对令牌中的组织归属信息（如audience、subject等关键claims）进行严格限制，IAM就无法区分该令牌究竟来自哪个组织，从而可能被"混淆"，误将其他组织的合法用户当作当前组织的授权用户。这就导致攻击者可以利用自己在同一共享身份提供商中的合法身份，诱导IAM代其执行原本仅授权给目标组织的操作，最终实现跨组织的越权行为。
因此，在共享OIDC场景下，如果缺乏对关键claims的精确校验，IAM就可能在不知情的情况下触发混淆代理问题。
#### 共享身份提供商的访问控制
当你在IAM中创建或修改OIDC身份提供商的信任委托时，信任策略中必须要包含oidc:iss和oidc:aud条件键；如果是共享的身份提供商，建议用户增加oidc:sub条件键。如果在信任委托的信任策略中未配置oidc:iss和oidc:aud条件键，则信任委托的创建或更新将失败并报错 。有关条件键的更多信息，请参见[STS身份策略授权参考](https://support.huaweicloud.com/api-iam5/iam_02_1125.html)。
- **oidc:iss条件键**
  oidc:iss条件键用于验证发行者（Issuer）是否与您在信任策略中指定的内容匹配。对应OIDC令牌中的iss字段，是OIDC身份提供商发布者的URL。
  针对如下示例：
  ```
  {
      "iss": "https://accounts.example-idp.com",
      "aud": "my-backend-service",
      "sub": "a1b2c3d4e5f6g7h8"
  }
  ```
  oidc:iss条件键的值为：https://accounts.example-idp.com。
  
- **oidc:aud条件键**
  oidc:aud条件键用于验证audience（受众）是否与您在信任策略中指定的内容匹配。这个条件键取值如下：
  - 如果OIDC令牌中没有azp字段，oidc:aud条件键取值为OIDC令牌中的aud字段。
  
  - 如果OIDC令牌中有azp字段，oidc:aud条件键取值为OIDC令牌中的azp字段。
   
  在使用oidc:aud条件键编写策略时，用户必须了解OIDC身份提供商为应用程序颁发的OIDC令牌中是否设置了azp字段。
  1. OIDC令牌中没有azp字段示例：
     ```
     {
         "iss": "https://accounts.example-idp.com",
         "aud": "my-backend-service",
         "sub": "550e8400-e29b-41d4-a716-446655440000"
     }
     ```
     oidc:aud条件键的值为：my-backend-service
     
  
  2. OIDC令牌中有azp字段示例：
     ```
     {
         "iss": "https://accounts.example-idp.com",
         "aud": "my-backend-service",
         "azp": "my-frontend-app",
         "sub": "550e8400-e29b-41d4-a716-446655440000"
     }
     ```
     oidc:aud条件键的值为：my-frontend-app
     
  
  3. OIDC令牌中aud为多值，且包含azp字段示例：
     ```
     {
         "iss": "https://accounts.example-idp.com",
         "aud": [
             "my-backend-service",
             "my-mobile-app"
         ],
         "azp": "my-frontend-app",
         "sub": "550e8400-e29b-41d4-a716-446655440000"
     }
     ```
     oidc:aud条件键的值为：my-frontend-app
     
    
- **oidc:sub条件键**
  oidc:sub条件键用于验证subject（主体标识）是否与您在信任策略中指定的内容匹配。对应于OIDC令牌中的sub字段，是OIDC身份提供商范围内用户的唯一标识符。
  针对如下示例：
  ```
  {
      "iss": "https://accounts.example-idp.com",
      "aud": "my-backend-service",
      "sub": "550e8400-e29b-41d4-a716-446655440000"
  }
  ```
  oidc:sub条件键的值为：550e8400-e29b-41d4-a716-446655440000
  
 
通过上述几种条件键的访问控制可以有效防止混淆代理问题，可以编写如下信任策略示例：
```
{
    "Version": "5.0",
    "Statement": [
        {
            "Action": [
                "sts:agencies:assumeWithOIDC"
            ],
            "Effect": "Allow",
            "Principal": {
                "Federated": [
                    "iam::{account-id}:oidcProvider:{provider-name}"
                ]
            },
            "Condition": {
                "StringEquals": {
                    "oidc:iss": [
                        "https://accounts.example-idp.com"
                    ],
                    "oidc:aud": [
                        "my-backend-service"
                    ],
                    "oidc:sub": [
                        "550e8400-e29b-41d4-a716-446655440000"
                    ]
                }
            }
        }
    ]
}
```
