日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

通過KMS托管實例密碼憑證

當您的應用需要訪問云數據庫 Tair(兼容 Redis)實例時,您可以將實例賬號口令存儲在KMS的憑據中(即實例憑據),業務應用通過集成阿里云SDK、KMS SDK或憑據SDK向KMS動態獲取賬號口令。您還可以為憑據配置輪轉,以減少賬號口令的泄露風險。

功能介紹

在KMS托管云數據庫 Tair(兼容 Redis)實例的賬號口令時,應用程序將無需配置靜態數據庫賬號口令。管理員在KMS創建實例憑據,應用程序調用GetSecretValue接口獲取實例賬號和口令信息,用于訪問實例。

例如您在KMS中自定義的實例憑證為username時,KMS最終會在實例中創建usernameusername_clone賬號,實現雙賬號托管,并使用該賬號訪問實例,相比較單賬號,雙賬號托管場景下應用程序的可用性、安全性更高。您可以在KMS控制臺設置賬號輪轉策略,默認情況下KMS每24小時會進行賬號輪轉,即使用不同的賬號登錄實例,提高安全性。更多信息請參見Redis/Tair憑據

重要

請勿在云數據庫 Tair(兼容 Redis)控制臺中修改或刪除由KMS創建的賬號口令,以避免業務失敗。

image

使用限制

  • 不支持在控制臺修改KMS創建的托管型賬號的密碼,您可以前往KMS控制臺通過手動輪轉或配置自動輪轉策略更換該密碼,更多信息請參見輪轉Redis/Tair憑據

  • 不支持在控制臺刪除KMS創建的托管型賬號,如需刪除,請前往KMS控制臺執行刪除操作,更多信息請參見刪除Redis憑據

  • 不支持在控制臺修改KMS創建的托管型賬號的備注信息。

前提條件

  • 已創建ECS實例,用于連接實例實例。本示例ECS的操作系統為Alibaba Cloud Linux 3.2104 LTS 64位,同時已安裝JAVA 1.8.0。

  • 若使用RAM用戶(子賬號)或RAM角色管理實例憑據,您需要為該角色授予系統權限策略AliyunKMSSecretAdminAccess。具體操作請參見授權權限

操作步驟

  1. 創建并啟用KMS。具體操作請參見創建和啟用KMS

    創建KMS時需選擇VPC,請選擇與ECS相同的VPC網絡。

    若您已創建KMS,請在KMS中添加ECS的VPC網絡,具體操作請參見配置VPC

  2. 創建應用接入點。具體操作請參見創建應用接入點

    創建后,瀏覽量會自動下載ClientKey信息,包含應用身份憑證內容(ClientKeyContent,JSON文件)憑證口令(ClientKeyPassword),請妥善保存。

  3. 下載KMS的CA證書,您可以在KMS控制臺的實例管理頁面進行下載,更多信息請參見獲取KMS的CA證書

  4. 創建一個用戶主密鑰。具體操作請參見密鑰管理快速入門

  5. 創建云數據庫 Tair(兼容 Redis)實例憑據。具體操作請參見創建Redis/Tair憑據

  6. 編寫Java測試代碼。

    1. 在項目中添加Maven依賴,從Maven倉庫中自動下載Java安裝包。同時還可以將項目依賴打進作業JAR包,需增加下述<build>。

          <dependencies>
              <dependency>
                  <groupId>redis.clients</groupId>
                  <artifactId>jedis</artifactId>
                  <version>5.1.0</version>
              </dependency>
              <dependency>
                  <groupId>com.aliyun</groupId>
                  <artifactId>alibabacloud-dkms-gcs-sdk</artifactId>
                  <version>0.5.2</version>
              </dependency>
              <dependency>
                  <groupId>com.aliyun</groupId>
                  <artifactId>tea</artifactId>
                  <version>1.2.3</version>
              </dependency>
              <dependency>
                  <groupId>org.slf4j</groupId>
                  <artifactId>slf4j-api</artifactId>
                  <version>1.7.10</version>
              </dependency>
              <dependency>
                  <groupId>ch.qos.logback</groupId>
                  <artifactId>logback-classic</artifactId>
                  <version>1.2.9</version>
              </dependency>
          </dependencies>
      
          <build>
              <plugins>
                  <plugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-assembly-plugin</artifactId>
                      <version>3.3.0</version>
                      <configuration>
                          <archive>
                              <manifest>
                                  <mainClass>
                                      com.aliyun.KMSJedisTest
                                  </mainClass>
                              </manifest>
                          </archive>
                          <descriptorRefs>
                              <descriptorRef>jar-with-dependencies</descriptorRef>
                          </descriptorRefs>
                      </configuration>
                      <executions>
                          <execution>
                              <id>assemble-all</id>
                              <phase>package</phase>
                              <goals>
                                  <goal>single</goal>
                              </goals>
                          </execution>
                      </executions>
                  </plugin>
                  <plugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-compiler-plugin</artifactId>
                      <configuration>
                          <source>1.8</source>
                          <target>1.8</target>
                      </configuration>
                  </plugin>
              </plugins>
          </build>
    2. 編寫主代碼KMSJedisTest.java

      說明

      為了防止每次新建連接都訪問KMS獲取密碼,本示例中增加了一個緩存credentialCacheTime(默認為600s),在緩存周期內,會返回緩存的密碼值,而不去訪問 KMS,您可以通過setCredentialCacheTime接口來調整緩存的時間,建議不要低于10分鐘。

      package com.aliyun;
      
      import java.time.Duration;
      
      import redis.clients.jedis.DefaultJedisClientConfig;
      import redis.clients.jedis.HostAndPort;
      import redis.clients.jedis.Jedis;
      import redis.clients.jedis.JedisPool;
      
      public class KMSJedisTest {
          public static void main(String[] args) throws Exception {
              if (args.length < 2) {
                  System.out.println(
                      "Please input kmsEndpoint, clientKeyFilePath, clientKeyPass, caCertPath, secretName, redisHost");
                  return;
              }
      
              String endpoint = args[0];
              String clientKeyFilePath = args[1];
              String clientKeyPass = args[2];
              String caCertPath = args[3];
              String secretName = args[4];
              KMSRedisCredentialsProvider kmsRedisCredentialsProvider = new KMSRedisCredentialsProvider(endpoint,
                  clientKeyFilePath, clientKeyPass, caCertPath, secretName);
              kmsRedisCredentialsProvider.setCredentialCacheTime(Duration.ofSeconds(10)); // 設置緩存時間,防止頻繁請求KMS
      
              String redisHost = args[5];
              JedisPool jedisPool = new JedisPool(HostAndPort.from(redisHost),
                  DefaultJedisClientConfig.builder().credentialsProvider(kmsRedisCredentialsProvider).build());
      
              for (int i = 0; i < Integer.MAX_VALUE; i++) {
                  Thread.sleep(1000);
                  try (Jedis jedis = jedisPool.getResource()) {
                      System.out.println(jedis.set("" + i, "" + i));
                      System.out.println(jedis.get("" + i));
                  } catch (Exception e) {
                      System.out.println(e);
                  }
              }
          }
      }
      
    3. 編寫KMSRedisCredentialsProvider.java

      package com.aliyun;
      
      import java.time.Duration;
      import java.time.LocalDateTime;
      import java.time.format.DateTimeFormatter;
      
      import org.json.JSONObject;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import redis.clients.jedis.DefaultRedisCredentials;
      import redis.clients.jedis.RedisCredentials;
      import redis.clients.jedis.RedisCredentialsProvider;
      
      import com.aliyun.dkms.gcs.openapi.models.Config;
      import com.aliyun.dkms.gcs.sdk.Client;
      import com.aliyun.dkms.gcs.sdk.models.*;
      
      public class KMSRedisCredentialsProvider implements RedisCredentialsProvider {
          private static final Logger logger = LoggerFactory.getLogger(KMSRedisCredentialsProvider.class);
      
          private final String endpoint;
          private final String clientKeyFilePath;
          private final String clientKeyPass;
          private final String caCertPath;
          private final String secretName;
          private static Client client = null;
      
          // credential cache time
          private Duration credentialCacheTime = Duration.ofSeconds(600);
          private DefaultRedisCredentials cachedCredentials = null;
          private LocalDateTime credentialsExpiration = null;
      
          public KMSRedisCredentialsProvider(String endpoint, String clientKeyFilePath, String clientKeyPass,
              String caCertPath, String secretName) {
              this.endpoint = endpoint;
              this.clientKeyFilePath = clientKeyFilePath;
              this.clientKeyPass = clientKeyPass;
              this.caCertPath = caCertPath;
              this.secretName = secretName;
              createClientInstance(endpoint, clientKeyFilePath, clientKeyPass, caCertPath);
          }
      
          public void setCredentialCacheTime(Duration credentialCacheTime) {
              this.credentialCacheTime = credentialCacheTime;
          }
      
          private static synchronized void createClientInstance(String endpoint, String clientKeyFilePath,
              String clientKeyPass, String caCertPath) {
              if (client == null) {
                  try {
                      client = new Client(new Config()
                          .setProtocol("https")
                          .setEndpoint(endpoint)
                          .setCaFilePath(caCertPath)
                          .setClientKeyFile(clientKeyFilePath)
                          .setPassword(clientKeyPass));
                  } catch (Exception e) {
                      logger.error("Init kms client failed", e);
                      throw new RuntimeException(e);
                  }
              }
          }
      
          @Override
          public RedisCredentials get() {
              try {
                  LocalDateTime now = LocalDateTime.now();
                  // Check cache
                  if (cachedCredentials != null && now.isBefore(credentialsExpiration)) {
                      return cachedCredentials;
                  }
      
                  GetSecretValueRequest request = new GetSecretValueRequest().setSecretName(secretName);
                  GetSecretValueResponse getSecretValueResponse = client.getSecretValue(request);
                  logger.debug("Now: " + now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) +
                      ", getSecretValueRequest: " + request);
                  String secretData = getSecretValueResponse.getSecretData();
                  JSONObject secretObject = new JSONObject(secretData);
                  if (secretObject.get("AccountName") == null || secretObject.get("AccountPassword") == null) {
                      throw new IllegalArgumentException("secretData must contain AccountName and AccountPassword");
                  }
                  cachedCredentials = new DefaultRedisCredentials(secretObject.get("AccountName").toString(),
                      secretObject.get("AccountPassword").toString());
                  credentialsExpiration = now.plusSeconds(credentialCacheTime.getSeconds());
                  return cachedCredentials;
              } catch (Exception e) {
                  logger.error("get secret failed", e);
                  throw new RuntimeException(e);
              }
          }
      
          @Override
          public void prepare() {
              // do nothing
          }
      
          @Override
          public void cleanUp() {
              // do nothing
          }
      }
      
    4. 將整個項目打進JAR包,命令為mvn package

  7. 在ECS中,通過Java SDK連接實例。

    本示例的語法如下:

    java -jar <kms-redis-jar-with-dependencies.jar> <kmsEndpoint> <clientKeyFilePath> <clientKeyPass> <caCertPath> <secretName> <redisHost>

    參數說明:

    • kms-redis-jar-with-dependencies.jar:JAR包,請使用后綴為jar-with-dependencies的JAR包。

    • kmsEndpoint:KMS的VPC地址,您可以在KMS實例詳情頁獲取。

    • clientKeyFilePath:接入點應用身份憑證內容,為步驟2下載的JSON文件。

    • clientKeyPass:接入點憑證口令,內容在步驟2下載的TXT文件中。

    • caCertPath:KMS實例的CA證書,為步驟3下載的PEM文件。

    • secretName:步驟5中創建實例憑據的名稱。

    • redisHost:實例的VPC連接地址與端口號,例如r-bp1g727yrai5yh****.redis.rds.aliyuncs.com:6379

    示例:

    java -jar kms-redis-samples-1.0-SNAPSHOT-jar-with-dependencies.jar kst-hzz6674e7fbw21x9x****.cryptoservice.kms.aliyuncs.com /root/clientKey_KAAP.6432ddc6-f23a-4d78-ac84-****4598206b.json 267d1****1cda4415058e1d72ec49e0a /root/PrivateKmsCA_kst-hzz6674e7fbw21x9x****.pem kms-redis r-bp1g727yrai5yh****.redis.rds.aliyuncs.com:6379

    預期返回如下,表示已成功連接:

    0
    OK
    1
    OK
    2
    OK
    3
    OK
    4
    OK
  8. 您可以在KMS控制臺執行立即輪轉憑據測試,具體操作請參見輪轉Redis/Tair憑據

    輪轉表示KMS將使用另一個賬號(usernameusername_clone)訪問實例。

    此時,ECS的連接若仍正常,則表示當前可以實現密碼滾動功能。

    ...
    30
    OK
    31
    OK
    32
    OK
    33
    OK
  9. 在實例執行主從切換(HA)測試,觀察客戶端情況。

    預期返回如下,表示在HA時連接閃斷,KMS實例更新憑據并成功重新連接:

    138
    OK
    139
    redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream.
    OK
    142
    OK
    143
    OK

相關文檔