
# 单用户凭据轮换策略
#### 简介
单用户凭据轮换是指一个凭据中更新一个用户所保存的信息。
这是最基础的凭据轮换策略，适用于大多数日常使用场景。
例如：
- 访问数据库。凭据轮换时不会删除数据库连接，轮换后的新连接使用新凭据。
- 访问允许用户创建一个用户账户的服务，例如以电子邮件地址作为用户名。服务通常允许用户根据需要经常更改密码，但用户无法创建其他用户或更改用户名。
- 根据需要创建的用户，称为临时用户。
- 以交互方式输入密码的用户，而不是让应用程序以编程方式从凭据管理服务中检索密码。这种类型的用户不需要更改用户名和密码。
 
#### 约束条件
您首先需要确保您的账号拥有KMS Administrator或者KMS CMKFullAccess权限，详情见[DEW权限管理](https://support.huaweicloud.com/productdesc-dew/dew_01_0018.html)。
#### 轮换凭据的API
您可以调用以下API，在本地进行凭据轮换。
| API名称                                                                        | 说明                     |
|:---|:---|
| [创建凭据版本](https://support.huaweicloud.com/api-dew/CreateSecretVersion.html)   | 创建新的凭据版本。              |
| [查询凭据版本与凭据值](https://support.huaweicloud.com/api-dew/ShowSecretVersion.html) | 查询指定凭据版本的信息和版本中的明文凭据值。 |
   
#### 单账号凭据轮换代码示例
1. 通过华为云控制台，创建一个凭据，详情见[创建凭据](https://support.huaweicloud.com/usermanual-dew/dew_01_9993.html)。
2. 请准备基础认证信息。
   - ACCESS_KEY: 华为账号Access Key
   
   - SECRET_ACCESS_KEY: 华为账号Secret Access Key
   
   - PROJECT_ID: 华为云局点项目ID，请参见[华为云局点项目](https://support.huaweicloud.com/api-iam/iam_17_0002.html)。
   
   - CSMS_ENDPOINT: 华为云CSMS服务访问终端地址。
   
   - 认证用的ak和sk直接写到代码中有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全。
   
   - 本示例以ak和sk保存在环境变量中来实现身份验证为例，运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。
    
3. 进行单用户凭据轮换。 示例代码中：
   - 凭据名称：华为云控制台创建的凭据名称。
   
   - 凭据内容：华为云控制台创建的凭据中所保存的值。
   
   - 凭据版本Id：华为云控制台创建凭据后自行生成凭据ID。
   
   - 凭据版本：LATEST_VERSION
     ```
     import com.huaweicloud.sdk.core.auth.BasicCredentials;
     import com.huaweicloud.sdk.csms.v1.CsmsClient;
     import com.huaweicloud.sdk.csms.v1.model.CreateSecretVersionRequest;
     import com.huaweicloud.sdk.csms.v1.model.CreateSecretVersionRequestBody;
     import com.huaweicloud.sdk.csms.v1.model.CreateSecretVersionResponse;
     import com.huaweicloud.sdk.csms.v1.model.ShowSecretVersionRequest;
     import com.huaweicloud.sdk.csms.v1.model.ShowSecretVersionResponse;
     public class CsmsSingleAccountExample {
         /**
          * 基础认证信息：
          * - ACCESS_KEY: 华为账号Access Key
          * - SECRET_ACCESS_KEY: 华为账号Secret Access Key
          * - PROJECT_ID: 华为云局点项目ID 详情见https://support.huaweicloud.com/productdesc-iam/iam_01_0023.html
          * - CSMS_ENDPOINT: 华为云CSMS服务访问终端地址 详情见https://support.huaweicloud.com/api-dew/dew_02_0052.html
          * - 认证用的ak和sk直接写到代码中有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全。
          * - 本示例以ak和sk保存在环境变量中来实现身份验证为例，运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。
          */    
         private static final String ACCESS_KEY = System.getenv("HUAWEICLOUD_SDK_AK");
         private static final String SECRET_ACCESS_KEY = System.getenv("HUAWEICLOUD_SDK_SK");
         private static final String PROJECT_ID = "<ProjectID>";
         private static final String CSMS_ENDPOINT = "<CsmsEndpoint>";
         // 用来查询凭据最新版本详情的版本Id
         private static final String LATEST_VERSION = "latest";
         public static void main(String[] args) {
             String secretName = args[0];
             String secretString = args[1];
             singleAccountRotation(secretName, secretString);
         }
         /**
          * 凭据轮换-单账号模式代码示例
          *
          * @param secretName   凭据名称
          * @param secretString 凭据内容
          */
         private static void singleAccountRotation(String secretName, String secretString) {
             // 将新版凭据托管到凭据管理服务
             createNewSecretVersion(secretName, secretString);
             // 通过凭据版本“latest”查询到最新版本凭据
             ShowSecretVersionResponse secretResponseByLatest = showSecretVersionDetail(secretName, LATEST_VERSION);
             assert secretResponseByLatest.getVersion().getSecretString().equals(secretString);
         }
         /**
          * 创建凭据示例
          * 使用不附带版本状态的方式添加凭据版本，则程序默认将SYSCURRENT版本状态指向当前新创建的版本
          *
          * @param secretName   凭据名称
          * @param secretString 凭据内容
          * @return
          */
         private static CreateSecretVersionResponse createNewSecretVersion(String secretName, String secretString) {
             CsmsClient csmsClient = getCsmsClient();
             CreateSecretVersionRequest createSecretVersionRequest = new CreateSecretVersionRequest()
                     .withSecretName(secretName)
                     .withBody(new CreateSecretVersionRequestBody().withSecretString(secretString));
             CreateSecretVersionResponse secretVersion = csmsClient.createSecretVersion(createSecretVersionRequest);
             System.out.printf("Created new version success, version id:%s", secretVersion.getVersionMetadata().getId());
             return secretVersion;
         }
         /**
          * 查询指定版本凭据
          *
          * @param secretName 查询凭据名称
          * @param versionId  查询凭据版本Id
          * @return
          */
         private static ShowSecretVersionResponse showSecretVersionDetail(String secretName, String versionId) {
             ShowSecretVersionRequest showSecretVersionRequest = new ShowSecretVersionRequest().withSecretName(secretName)
                     .withVersionId(versionId);
             CsmsClient csmsClient = getCsmsClient();
             ShowSecretVersionResponse secretDetail = csmsClient.showSecretVersion(showSecretVersionRequest);
             System.out.printf("Query latest version success. version id:%s",
     secretDetail.getVersion().getVersionMetadata().getId());
             return secretDetail;
         }
         /**
          * 获取CSMS服务客户端
          *
          * @return
          */
         private static CsmsClient getCsmsClient() {
             BasicCredentials auth = new BasicCredentials()
                     .withAk(ACCESS_KEY)
                     .withSk(SECRET_ACCESS_KEY)
                     .withProjectId(PROJECT_ID);
             return CsmsClient.newBuilder().withCredential(auth).withEndpoint(CSMS_ENDPOINT).build();
         }
     }
     ```
     
    
 
