如何在雲上安全高效地存放您的配置 - 代碼示例

概述

在以前文章 如何在阿里雲上安全的存放您的配置 - 續 中,咱們講述了雲上安全存放配置的方法。基於前文原理,本文將以代碼示例方式講解如何基於配置中心產品 ACM 將應用配置(如 數據庫鏈接配置)從應用程序代碼中解耦,從而達到如下目的:html

  • 安全合規:應用程序和生產環境上將不須要發佈和持久化任何程序敏感信息;
  • 敏捷發佈:數據庫鏈接串配置修改動態生效,不須要程序從新發布甚至重啓;

示例程序架構和準備工做

文章中的示例將分爲如下幾個步驟:java

  • 配置 ACM 和 RAM,設置 ECS RAM Role,並進行 ACM 受權,來受權 ECS 上的應用免 AK/SK(即 AccessKey/SecretKey) 來調用 ACM;
  • 讀取配置程序編寫:使用 ACM Java SDK 動態讀取配置內容,來進行數據庫配置。mysql

    1. 其中,程序中不含任何敏感配置,如數據庫鏈接串,阿里雲 AK/SK等;sql

      1. 數據庫鏈接串在 ACM 上動態刷新,應用不停機。

程序代碼架構以下圖所示:數據庫

image.png | left | 544x304

開始前,用戶應準備好:安全

  • 在阿里雲上購買 ECS;
  • 在阿里雲上開通 ACM, RAM 等免費服務產品;
  • 準備好數據庫,可在阿里雲上開通數據庫或在 ECS 上自行搭建,數據庫裏面可準備好一張 user 表,並準備若干記錄;
  • 準備好可訪問數據庫的 Java 應用程序 (或從這裏下載完整代碼示例下載)。

配置ACM和RAM

該章節分爲兩個部分:架構

  • 在 ACM 中配置相關敏感信息;
  • 經過 RAM 設置用戶的 ECS 的 RAM Role;

在 ACM 控制檯中建立配置

代碼示例所需數據庫鏈接的配置運維

  • Data ID:
    com.alibaba.cloud.acm:jdbc-sample.properties
  • Group:非必選,在「更多高級選項」中,默認值爲「DEFAULT_GROUP」
    DEFAULT_GROUP
  • 配置內容, 可根據實際狀況進行配置:
    jdbc.url=xxx

jdbc.username=xxx
jdbc.password=xxxide

image.png | left | 520x348

配置 ECS RAM Role

在ACM程序訪問中,用戶可設置 AccessKey、SecretKey 屬性的方式來訪問 ACM 產品,可是在本文中推薦經過「ECS 實例角色」的方式來訪問ACM。該方式自動獲取臨時憑證,提升安全性和下降運維成本,憑證週期由 ACM SDK 自動維護,應用運行時只需設置 JVM 參數「-Dram.role.name=ramRoleName」,ramRoleName」,ramRoleName 爲授予該 ECS 的 RAM 角色名稱,如 ECS-RAM。運行命令以下:函數

java -jar -Dram.role.name=ECS-RAM sample-1.0-SNAPSHOT-jar-with-dependencies.jar

關於如何設置 ECS 實例角色,請參考「ECS 實例角色」文章。爲減小文章篇幅,本文不贅述了。

讀取配置程序編寫

該章節分爲三個部分:

  • 在 ACM 中初始化 ACM 鏈接,用戶僅需填寫配置信息,無需填寫 AK/SK 敏感信息;
  • 讀取 ACM 配置,並監聽配置變化;
  • 相關業務代碼編寫,根據需求創建數據庫鏈接並查詢數據;

在程序中初始化 ACM,並讀取相關配置

  • namespace:命名空間 ID,在控制檯「命名空間詳情」的「命名空間ID」處能夠獲取到
  • endpoint: ACM 鏈接域,在控制檯「命名空間詳情」的「End Point」處能夠獲取到
private void initACM() {
    Properties properties = new Properties();
    String namespace = "1ca01ca0-11b0-1e01-0df1-d1010101bc10";
    String endpoint = "acm.aliyun.com";
    properties.put("endpoint", endpoint);
    properties.put("namespace", namespace);
    ConfigService.init(properties);
}

經過 ACM 獲取配置並監聽配置變化

獲取數據庫鏈接配置的內容,而且添加配置監聽器。當數據庫鏈接配置的內容須要變動,在 ACM 控制檯修改後,程序實時接收到新的內容,新的數據庫鏈接也實時生效,不中斷程序的運行。

  • dataId:剛剛新建配置時 Data ID 所填寫的值
  • group:剛剛新建配置時 Group 所填寫的值,默認爲「DEFAULT_GROUP」,隱藏在「更多高級選項」中
private void initJDBCProperties() throws ConfigException {
    String dataId = "com.alibaba.cloud.acm:jdbc-sample.properties";
    String group = "DEFAULT_GROUP";
    properties = ConfigService.getConfig2Properties(dataId, group, 3000);
    // 添加配置監聽
    ConfigService.addListener(dataId, group, new ConfigChangeListener() {
        @Override
        public void receiveConfigInfo(String content) {
            Properties properties = new Properties();
            try {
                properties.load(new StringReader(content));
            } catch (IOException e) {
                LOGGER.error("addListener", e);
            }
            SampleApp.this.properties = properties;
        }
    });
}

創建數據庫鏈接並查詢數據

從 ACM 獲取到的鏈接數據庫所需的地址、用戶名、密碼,經過 MySQL JDBC 驅動包「mysql-connector-java」與 MySQL 服務創建鏈接。接着,再查詢「user」表的總記錄數,返回給函數調用者。

注: 程序中使用的鏈接信息爲ACM中保存的最新的數據庫鏈接信息,鏈接信息經過上面的ACM的監聽配置程序進行動態刷新,從而保證爲最新。

private int count() {
    String url = properties.getProperty("jdbc.url");
    String username = properties.getProperty("jdbc.username");
    String password = properties.getProperty("jdbc.password");
    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null;
    try {
        connection = DriverManager.getConnection(url, username, password);
        statement = connection.createStatement();
        resultSet = statement.executeQuery("select count(*) from `user`");
        if (resultSet.next()) {
            return resultSet.getInt(1);
        }
    } catch (SQLException e) {
        LOGGER.error("count", e);
    } finally {
        close(connection, statement, resultSet);
    }
    return 0;
}

測試運行

若是你按照本片文章前面工做,完成了 ECS RAM Role 設置和受權之後,可在不設置任何 AK/SK 狀況下,將程序實例打包成可執行 jar 後,上傳到對應的 ECS 環境上運行便可。當程序運行時,如 如何在阿里雲上安全的存放您的配置 - 續 文章所描述的,程序將自動獲取臨時憑證訪問 ACM,憑證週期由 ACM SDK 自動維護。應用運行時只需設置 JVM 參數「-Dram.role.name=ramRoleName」,ramRoleName」,ramRoleName 爲授予該 ECS 的 RAM 角色名稱,如 ECS-RAM。運行命令以下:

java -jar -Dram.role.name=ECS-RAM sample-1.0-SNAPSHOT-jar-with-dependencies.jar

本代碼示例經過 ACM 控制檯配置 JDBC 的鏈接屬性,再使用 ACM Java SDK 讀取配置內容,與 MySQL 創建鏈接,查詢「用戶」數據,最後將結果打印出來,控制檯輸出內容以下:

總記錄數: 9

注:若是是在您本身電腦上或本地測試,須要手動設置 AccessKey、SecretKey 屬性,才能夠訪問 ACM 產品,目前支持三種設置方式,本示例可以使用環境變量,以下:

spas_accessKey=xxx 
spas_secretKey=xxx

代碼下載

完整代碼示例下載

參看文檔

相關文章
相關標籤/搜索