# 基于SAML协议的信任委托SSO概述
华为云联邦身份认证支持使用SAML 2.0协议，这是一种外部身份提供商广泛支持的开放标准。该功能支持单点登录 (SSO)，使用户无需创建IAM用户，也可以授权他人登录华为云管理控制台或直接调用API操作。
IAM SAML身份联邦身份认证支持以下使用案例：
- **允许联邦主体调用华为云API访问和操作华为云资源。**
  在该场景中，用户可使用外部身份提供商 (IdP) 生成的SAML断言（作为身份验证响应的一部分）来获取临时安全凭证，从而调用华为云API。
  该机制与IAM支持的其他联邦方式（如OIDC联邦身份认证）类似。
  
- **允许联邦主体登录华为云管理控制台访问和操作华为云资源。**
  在该场景中，用户从企业身份提供商门户发起登录请求，选择华为云作为目标应用后，会被重定向至华为云控制台，无需再次输入华为云的登录凭证。
  该机制支持通过第三方身份提供商实现对华为云控制台的单点登录 (SSO)。
  
 
#### 使用基于SAML协议的SSO对华为云进行API访问
假设您需要想给公司的员工授权访问华为云OBS的桶资源, 您可以允许员工可通过外部身份提供商（IdP）生成的SAML断言，来获取华为云的临时安全凭证，从而通过调用华为云API访问OBS的桶资源。
在此架构下，员工本身不需要拥有华为云账号或IAM用户，其所有OBS的桶资源操作均通过SAML断言获取的临时安全凭证调用华为云API完成。
- **IAM侧配置**
  如下图所示，管理员在IAM侧完成与外部身份提供商的信任建立及权限配置。
  图1在IAM侧配置身份提供商和信任委托   
  ![](https://support.huaweicloud.com/usermanual-iam5/zh-cn_image_0000002555603184.png "点击放大")
  **主要步骤包括：**
  1. 创建IAM SAML身份提供商，用于接入外部身份系统；
  
  2. 创建IAM信任委托，建立与身份提供商之间的信任关系；
  
  3. 为信任委托配置身份策略，定义可被授予的资源权限范围。
   
  通过上述配置，云平台完成对外部身份的信任初始化，为后续基于SAML的访问控制提供基础。
  
- **访问流程**
  使用过程如下：
  图2访问流程   
  ![](https://support.huaweicloud.com/usermanual-iam5/zh-cn_image_0000002580300969.png "点击放大")
  1. 组织中的用户使用客户端应用程序请求外部身份提供商进行身份验证。
  
  2. 外部身份提供商根据组织的身份存储对用户进行身份验证。
  
  3. 外部身份提供商构建一个具有用户相关信息的SAML断言，并将此断言发送到客户端应用程序。如果你为SAML外部身份提供商启用SAML加密，那么此断言将由外部身份提供商加密。
  
  4. 客户端应用程序调用STS AssumeAgencyWithSAML API，并传递SAML身份提供商的URN、Agency URN以及来自外部身份提供商的SAML断言。
  
  5. （可选）STS 使用您从外部外部身份提供商上传的私有密钥来解密SAML加密断言。
  
  6. STS AssumeAgencyWithSAML API返回临时安全凭证给客户端应用程序。
  
  7. 客户端应用程序使用临时安全凭证来调用OBS API操作桶资源。
    
 
#### 基于SAML协议的SSO配置概述
在使用前面方案和图表中所述的基于SAML 2.0 的联邦身份认证之前，您必须先配置组织的身份提供商和您的华为云账号，使之相互信任。以下步骤概述了建立此类信任关系的一般流程, 组织需具备一个支持SAML 2.0协议的身份提供商，以实现基于标准协议的SAML联邦身份认证。
**配置外部身份提供商与华为云之间的信任关系** ：
1. 配置组织的身份提供商（外部身份提供商）与华为云之间的信任关系。首先，在外部身份提供商中上传华为云的SAML元数据文件，将华为云注册为服务提供商：
   - SAML断言未加密场景：https://auth.huaweicloud.com/authui/v5/saml/metadata.xml
   
   - SAML断言加密场景：https://auth.huaweicloud.com/authui/v5/saml/{provider_id}/metadata.xml
    
2. 在您的外部身份提供商中生成SAML元数据XML文件，用于向华为云准确描述该IdP的端点地址及公钥证书。该文件必须包含：发布者名称、创建时间、过期时间以及用于验证SAML断言的签名证书（公钥）。
   ![](https://support.huaweicloud.com/usermanual-iam5/public_sys-resources/warning_3.0-zh-cn.png)
   如[SAML V2.0 Metadata Interoperability Profile Version 1.0](https://docs.oasis-open.org/security/saml/Post2.0/sstc-metadata-iop-os.html)所定义，IAM在进行SAML断言验证时，不会校验元数据文件中X.509证书的有效期（仅在上传元数据文件时校验证书是否过期）。若 X.509 证书在元数据文件上传后发生过期，IAM不会执行任何额外处理，意味着您的身份提供商仍然可以正常使用。建议您根据组织的治理与安全策略，定期监控证书到期时间，并及时完成证书轮换，以降低潜在风险。
   
3. 启用SAML断言加密时，需在外部身份提供商使用公钥加密断言，并将对应私钥上传至IAM，由华为云STS Security Token负责解密SAML响应。
4. 在IAM中创建一个或多个信任委托，并在信任委托的信任策略中将SAML身份提供商设置为受信任主体。信任委托的信任策略定义了谁可以在华为云中切换该信任委托。
   ![](https://support.huaweicloud.com/usermanual-iam5/public_sys-resources/caution_3.0-zh-cn.png)
   在信任委托的信任策略中使用的SAML身份提供商必须与信任委托位于同一账号中。
   
5. 在外部身份提供商中配置SAML断言，将企业中的用户或用户组映射到对应的IAM信任委托。不同用户或组可以映射到不同信任委托，具体配置方式取决于所使用的外部身份提供商。
6. 如果外部身份提供商支持访问华为云控制台的单点登录（SSO），可以在外部身份提供商中配置控制台会话的最大持续时间。
7. 在您的外部身份提供商调用华为云STS AssumeAgencyWithSAML API，请求中需要包含：SAML身份提供商URN、目标IAM信任委托URN，以及从外部身份提供商获取的SAML断言。IAM会校验该请求是否来自受信任的外部身份提供商。
8. 如果调用成功，AssumeAgencyWithSAML API将返回临时安全凭证，应用程序可以使用该凭证访问华为云资源。有关更多信息，请参阅[在IAM中创建SAML身份提供商](https://support.huaweicloud.com/usermanual-iam5/iam_01_1309.html)。
 
#### 用于SAML联邦身份认证访问华为云资源的信任委托概述
您在IAM中创建的信任委托将确定您组织中的SAML联邦主体在华为云中允许执行的操作。当您为信任委托创建信任策略时，您可以将先前创建的IAM身份提供商指定为信任主体。此外，您还可以使用Condition设置信任策略的条件，以便仅允许与特定SAML属性匹配的用户切换信任委托。
```
{
    "Version": "5.0",
    "Statement": [
        {
            "Action": [
                "sts:agencies:assumeWithSAML"
            ],
            "Effect": "Allow",
            "Condition": {
                "StringEquals": {
                    "saml:aud": [
                        "https://auth.huaweicloud.com/authui/v5/saml",
                        "https://auth.huaweicloud.com/authui/v5/saml/acs/{provider_id}"                 
                    ]
                }
            },
            "Principal": {
                "Federated": [
                    "iam::{account_id}:samlProvider:{saml_provider_name}"
                ]
            }
        }
    ]
}
```
![](https://support.huaweicloud.com/usermanual-iam5/public_sys-resources/note_3.0-zh-cn.png)
策略中的saml:aud条件键用于指定用户登录控制台时的目标登录URL，该登录URL必须与外部身份提供商在SAML断言中设置的Recipient属性值保持一致。
以下示例显示了的登录URL格式。
```
https://auth.huaweicloud.com/authui/v5/saml
```
如果需要SAML加密，则登录URL必须包含华为云分配给您的身份提供商ID，您可以在IAM SAML身份提供商详细信息页面上找到身份提供商ID。在以下示例中，登录URL会要求在登录路径附加/acs/{身份提供商ID}, 用于标识对应的IAM SAML身份提供商。
```
https://auth.huaweicloud.com/authui/v5/saml/acs/{provider_id}
```
对于该信任委托中的身份策略，您可以像任何信任委托一样指定权限。例如，如果允许您企业的用户管理ECS实例，您必须在身份策略中明确允许华为云ECS操作，如**ECSFullPolicy**系统策略中的操作。
#### 基于SAML协议的联邦主体唯一标识
在IAM中创建身份策略时，可根据用户的身份指定权限，这一点通常很有用。举例来说，对于已使用SAML联邦身份认证的用户，应用程序可能希望使用如下的结构保留华为云OBS服务中的信息：
```
obs-demo-bucket/app1/user1
obs-demo-bucket/app1/user2
obs-demo-bucket/app1/user3
```
您可以通过华为云OBS控制台或API创建存储桶（如obs-demo-bucket）以及固定文件夹（如app1），由于这些资源名称是静态的，因此可以在初始化阶段预先创建；但用户级文件夹（如 user1、user2 等）需要在运行时通过代码动态创建，因为在用户首次通过 SAML 联邦身份认证之前，无法获取用于标识用户的唯一信息。为支持在策略中引用与用户相关的资源路径，需要在 SAML 断言中提供可用于 IAM 策略 Condition 判断的用户标识条件键，例如 saml:namequalifier、saml:sub 和 saml:sub_type：
1. saml:namequalifier 条件键由Issuer（即 saml:iss 条件键的值）、华为云账号的ID以及IAM SAML提供商的名称计算得到的哈希值，作为一个SAML联邦主体的全局唯一标识。下面的伪代码展示了哈希值的计算方式： BASE64 ( SHA256 ( "https://example.com/saml" + "8c1eef3a241945f2113d3a6b0252e783" + "/MySAMLIdPName" ) )
   其中：
   - + 号：表示字符串拼接。
   
   - SHA256：表示生成 SHA256 消息摘要的函数。
   
   - Base64：表示将哈希输出转换为 Base-64 编码。
    
2. saml:sub 表示SAML断言中主体, 对应于断言中Subject属性中NameID的值，用于标识该用户在当前身份提供商上下文中的主体身份。
3. saml:sub_type表示主体的类型，即NameID 的格式，由SAML断言中NameID元素的Format属性定义。格式的典型示例是transient（临时）或 persistent（持久）：
   - 如果该格式包含前缀 urn:oasis:names:tc:SAML:2.0:nameid-format，该前缀将被移除。例如，urn:oasis:names:tc:SAML:2.0:nameid-format:transient 将作为 transient 返回。
   
   - 如果格式包含任何其他前缀，则直接返回该格式而不做任何修改。
    
 
以下示例展示了一种身份策略：通过使用saml:namequalifier与saml:sub的组合，实现在华为云OBS服务中按用户划分的文件夹授予访问权限。该身份策略要求访问华为云OBS中的资源时，其路径前缀必须同时包含 saml:namequalifier和saml:sub，以标识用户特定的文件夹。同时，身份策略中的Condition条件会校验saml:sub_type是否为persistent，以确保用户标识在不同会话中保持一致；若为transient，则每次会话生成的saml:sub 值可能不同，因此不能依赖该组合来定位和标识用户特定的文件夹。
```
{
    "Version": "5.0",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "obs:object:getObject"
            ],
            "Resource": [
                "obs:*:*:object:obs-demo-bucket-org-data/backup/1/1",
                "obs:*:*:object:obs-demo-bucket-org-data/backup/4yL3A2MdG23rQAUIdMcnT+/tY7AodhXrJuvki4IlBSU=/test"
            ]
        }
    ]
}
```
