移轉應用程式以使用適用於 PostgreSQL 的 Azure 資料庫的無密碼連線

本文說明如何從傳統驗證方法移轉至更安全、無密碼的 適用於 PostgreSQL 的 Azure 資料庫 連線。

對適用於 PostgreSQL 的 Azure 資料庫的應用程式要求必須經過驗證。 適用於 PostgreSQL 的 Azure 資料庫提供數種不同的方式,讓應用程式安全地連線。 其中一種方法是使用密碼。 不過,您應該盡可能在應用程式中優先使用無密碼連線。

比較驗證選項

當應用程式向適用於 PostgreSQL 的 Azure 資料庫進行驗證時,它會提供使用者名稱和密碼組來連線資料庫。 視身分識別的儲存位置而定,有兩種類型的驗證:Microsoft Entra 驗證和 PostgreSQL 驗證。

Microsoft Entra 驗證

Microsoft Entra 驗證是一種機制,可使用 Microsoft Entra ID 中定義的身分識別連線到適用於 PostgreSQL 的 Azure 資料庫。 透過使用 Microsoft Entra 認證,您可以集中管理資料庫使用者身份及其他 Microsoft 服務,簡化權限管理。

使用 Microsoft Entra ID 進行驗證可提供下列優點:

  • 以統一的方式跨 Azure 服務驗證使用者。
  • 在單一位置管理密碼原則和密碼輪換。
  • Microsoft Entra ID 支援多種形式的驗證,可消除儲存密碼的需求。
  • 客戶可透過外部(Microsoft Entra ID)群組管理資料庫權限。
  • 使用 PostgreSQL 資料庫使用者透過 Microsoft Entra 認證,在資料庫層級驗證身份。
  • 支援連接 適用於 PostgreSQL 的 Azure 資料庫 的應用程式的權杖認證。

PostgreSQL 驗證

您可以在 PostgreSQL 中建立帳戶。 如果你選擇用密碼作為帳號的憑證,請將這些憑證儲存在 user 資料表中。 因為 PostgreSQL 會儲存這些密碼,你需要自己管理密碼的輪替。

雖然你可以用密碼連接 適用於 PostgreSQL 的 Azure 資料庫,但使用時要小心。 絕不要在不安全的地方暴露密碼。 任何取得密碼存取權的人都可以進行認證。 例如,如果你不小心將連線字串提交到原始碼版本控制系統、透過不安全的電子郵件寄送、貼到錯誤的聊天對話中,或被未經授權的人看見,惡意使用者就可能存取該應用程式。 相反地,請考慮更新您的應用程式以使用無密碼連線。

引入無密碼連線

透過無密碼連線,您可以連線到 Azure 服務,而不需要在應用程式程式碼、其組態檔或環境變數中儲存任何認證。

許多 Azure 服務都支援無密碼連線,例如透過 Azure 受控識別。 這些技術提供強大的安全性功能,您可以使用 Azure 身分識別用戶端程式庫中的 DefaultAzureCredential 來實作。 在本教學課程中,您將瞭解如何更新現有的應用程式以使用 DefaultAzureCredential ,而不是連接字串等替代方案。

DefaultAzureCredential 支援多種身份驗證方法,並自動確定在運行時應該使用哪種身份驗證方法。 此方法可讓您的應用程式在不同的環境中使用不同的驗證方法 (本機開發與生產環境),而無需實作環境特定的程式碼。

您可以在DefaultAzureCredential中找到搜尋認證的順序和位置。 例如,在本機工作時, DefaultAzureCredential 通常會使用開發人員用來登入 Visual Studio 的帳戶進行驗證。 當應用程式部署至 Azure 時, DefaultAzureCredential 會自動切換為使用 受控識別。 此轉換不需要變更程式碼。

若要確保連線是無密碼的,您必須同時考量本端開發和生產環境。 如果任一位置都需要連接字串,則應用程式不會無密碼。

在本機開發環境中,您可以使用 Azure CLI、Azure PowerShell、Visual Studio 或 Visual Studio Code 或 IntelliJ 的 Azure 外掛程式進行驗證。 在此情況下,您可以在應用程式中使用該認證,而不是設定內容。

當您將應用程式部署至 Azure 裝載環境 (例如虛擬機器) 時,您可以在該環境中指派受控識別。 然後,您不需要提供認證即可連線到 Azure 服務。

備註

受控識別提供安全性身分識別來代表應用程式或服務。 身分識別是由 Azure 平台管理,不需要您佈建或輪替任何秘密。 您可以在 概觀 檔中深入瞭解受控識別。

移轉現有應用程式以使用無密碼連線

下列步驟說明如何移轉現有應用程式,以使用無密碼連線,而不是密碼型解決方案。

0)準備工作環境

首先,使用以下指令來設定一些環境變數。

export AZ_RESOURCE_GROUP=<YOUR_RESOURCE_GROUP>
export AZ_DATABASE_SERVER_NAME=<YOUR_DATABASE_SERVER_NAME>
export AZ_DATABASE_NAME=demo
export AZ_POSTGRESQL_AD_NON_ADMIN_USERNAME=<YOUR_AZURE_AD_NON_ADMIN_USER_DISPLAY_NAME>
export AZ_LOCAL_IP_ADDRESS=<YOUR_LOCAL_IP_ADDRESS>
export CURRENT_USERNAME=$(az ad signed-in-user show --query userPrincipalName --output tsv)

將預留位置取代為下列值,這些值在本文中被全程使用:

  • <YOUR_RESOURCE_GROUP>:你資源的資源群組名稱。
  • <YOUR_DATABASE_SERVER_NAME>:PostgreSQL 伺服器的名稱。 它在 Azure 中應該是唯一的。
  • <YOUR_AZURE_AD_NON_ADMIN_USER_DISPLAY_NAME>:Microsoft Entra 非系統管理員使用者的顯示名稱。 確保名稱是你 Microsoft Entra 租戶中的有效使用者。
  • <YOUR_LOCAL_IP_ADDRESS>: 你本機電腦的 IP 位址,從它上執行 Spring Boot 應用程式。 找到它的一種便捷方法是打開 whatismyip.akamai.com。

1) 設定適用於 PostgreSQL 的 Azure 資料庫

1.1) 啟用基於 Microsoft Entra ID 的身份驗證

要使用 適用於 PostgreSQL 的 Azure 資料庫 Microsoft Entra ID 存取權限,請先設定 Microsoft Entra 管理員使用者。 只有 Microsoft Entra 管理員使用者才能建立或啟用基於 Microsoft Entra ID 的認證使用者。

若要在建立伺服器之後設定 Microsoft Entra 系統管理員,請遵循在 適用於 PostgreSQL 的 Azure 資料庫 - 彈性伺服器中管理 Microsoft Entra 角色中的步驟。

備註

PostgreSQL 彈性伺服器可以建立多個 Microsoft Entra 系統管理員。

2) 設定 適用於 PostgreSQL 的 Azure 資料庫 以進行本機開發

2.1) 為本地IP配置防火牆規則

適用於 PostgreSQL 的 Azure 資料庫執行個體預設會受到保護。 他們有一個防火牆,不允許任何傳入連接。 要使用你的資料庫,你需要加入一個防火牆規則,允許你的本地 IP 位址存取資料庫伺服器。

由於您在本文開頭設定了本機 IP 位址,因此您可以執行下列命令來開啟伺服器的防火牆:

az postgres flexible-server firewall-rule create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_SERVER_NAME \
    --rule-name $AZ_DATABASE_SERVER_NAME-database-allow-local-ip \
    --start-ip-address $AZ_LOCAL_IP_ADDRESS \
    --end-ip-address $AZ_LOCAL_IP_ADDRESS \
    --output tsv

如果您要從 Windows 電腦上的適用於 Linux 的 Windows 子系統 (WSL) 連線到 PostgreSQL 伺服器,您必須將 WSL 主機識別碼新增至防火牆。

透過 WSL 執行以下指令,取得你主機的 IP 位址:

cat /etc/resolv.conf

在術語 nameserver後複製 IP 位址,然後使用以下指令設定 WSL IP 位址的環境變數:

export AZ_WSL_IP_ADDRESS=<the-copied-IP-address>

然後,使用下列命令將伺服器的防火牆開啟至 WSL 型應用程式:

az postgres flexible-server firewall-rule create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_SERVER_NAME \
    --rule-name $AZ_DATABASE_SERVER_NAME-database-allow-local-ip \
    --start-ip-address $AZ_WSL_IP_ADDRESS \
    --end-ip-address $AZ_WSL_IP_ADDRESS \
    --output tsv

2.2) 建立 PostgreSQL 非管理員使用者並授予權限

接下來,建立非系統管理員 Microsoft Entra 使用者,並將資料庫的所有 $AZ_DATABASE_NAME 許可權授與它。 您可以變更資料庫名稱 $AZ_DATABASE_NAME 以符合您的需求。

建立名為 create_ad_user_local.sql 的 SQL 指令碼,以建立非管理員使用者。 新增下列內容並儲存在本機:

cat << EOF > create_ad_user_local.sql
select * from pgaadauth_create_principal('$AZ_POSTGRESQL_AD_NON_ADMIN_USERNAME', false, false);
EOF

接著,使用以下指令執行 SQL 腳本並建立 Microsoft Entra 非管理員使用者:

psql "host=$AZ_DATABASE_SERVER_NAME.postgres.database.azure.com user=$CURRENT_USERNAME dbname=postgres port=5432 password=$(az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken) sslmode=require" < create_ad_user_local.sql

現在,請使用以下指令移除暫存的 SQL 腳本檔案:

rm create_ad_user_local.sql

備註

欲了解更多關於建立 PostgreSQL 使用者的資訊,請參閱「在 適用於 PostgreSQL 的 Azure 資料庫 建立使用者」。

3) 登錄並遷移應用程序代碼以使用無密碼連接

在本機開發時,請確認您是使用與您在 PostgreSQL 中獲指派該角色時相同的 Microsoft Entra 帳戶完成驗證。 透過 Azure CLI、Visual Studio、Azure PowerShell 或其他工具如 IntelliJ 進行認證。

使用下列命令,透過 Azure CLI 登入 Azure:

az login

接下來,使用下列步驟更新程式碼以使用無密碼連線。 雖然概念上相似,但每種語言都使用不同的實作細節。

  1. 在您的專案中,將下列參考新增到azure-identity-extensions套件中。 此程式庫包含實作無密碼連線所需的所有實體。

    <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-identity-extensions</artifactId>
        <version>1.0.0</version>
    </dependency>
    
  2. 在 JDBC URL 中啟用 Azure PostgreSQL 驗證外掛程式。 識別程式碼中目前建立 java.sql.Connection 以連線到適用於 PostgreSQL 的 Azure 資料庫的位置。 更新 url 和 user 於您的 application.properties 文件,以符合下列值:

    url=jdbc:postgresql://$AZ_DATABASE_SERVER_NAME.postgres.database.azure.com:5432/$AZ_DATABASE_NAME?sslmode=require&authenticationPluginClassName=com.azure.identity.extensions.jdbc.postgresql.AzurePostgresqlAuthenticationPlugin
    user=$AZ_POSTGRESQL_AD_NON_ADMIN_USERNAME
    
  3. 請將 $AZ_POSTGRESQL_AD_NON_ADMIN_USERNAME 以及這兩個 $AZ_DATABASE_SERVER_NAME 變數替換為您在本文開頭所設定的值。

在本機執行應用程式

進行這些程式碼變更後,請在本機執行您的應用程式。 如果你登入相容的 IDE 或命令列工具,例如 Azure CLI、Visual Studio 或 IntelliJ,新設定會自動接收你的本地憑證。 你在 Azure 中指派給本地開發使用者的角色,允許你的應用程式在本地連接 Azure 服務。

4) 配置 Azure 託管環境

當你設定應用程式使用無密碼連線並在本地執行後,同一套程式碼在部署到 Azure 後也能驗證 Azure 服務。 例如,部署至已指派受控識別的 Azure App 服務 執行個體的應用程式可以連線到 Azure 儲存體。

在本節中,你執行兩個步驟,讓你的應用程式能以無密碼方式在 Azure 主機環境中運行:

  • 指派 Azure 主機環境的管理的身分識別。
  • 請指派角色給管理式身分識別。

備註

Azure 也提供 服務連接器,可協助您將裝載服務與 PostgreSQL 連線。 透過使用 Service Connector 配置你的主機環境,你可以省去指派管理身份角色的步驟,因為 Service Connector 會幫你指派角色。 下一節說明如何以兩種方式設定 Azure 裝載環境:一種是透過服務連接器,另一種是直接設定每個裝載環境。

這很重要

服務連接器的命令需要 Azure CLI 2.41.0 或更新版本。

使用 Azure 入口網站指派受控識別

下列步驟示範如何為各種 Web 裝載服務指派系統指派的受控識別。 管理身份可以利用你先前設定的應用程式配置,安全地連接到其他 Azure 服務。

  1. 在 Azure App 服務 執行個體的主要概觀頁面上,從導覽窗格中選取 [身分識別]。

  2. 在 系統指派 索引標籤上,確保將 狀態 欄位設定為 開啟。 系統指派的身分識別是由 Azure 內部管理,並為您處理系統管理工作。 身分識別的詳細資料和識別碼永遠不會在您的程式碼中公開。

你也可以透過 Azure CLI 在 Azure 主機環境中指派受管理身份。

您可以使用 az webapp identity assign 命令將受控識別指派給 Azure App 服務 執行個體,如下列範例所示:

export AZ_MI_OBJECT_ID=$(az webapp identity assign \
    --resource-group $AZ_RESOURCE_GROUP \
    --name <service-instance-name> \
    --query principalId \
    --output tsv)

將角色指派給受管理的身分

接下來,將權限授與您指派的受控識別,以存取 PostgreSQL 執行個體。

如果你是用 Service Connector 連接服務,前一步的指令已經指派了角色,所以你可以跳過這一步。

測試應用程式

在將應用程式部署到主機環境之前,你需要再修改程式碼,因為應用程式是透過你為管理身份建立的使用者連接到 PostgreSQL。

更新您的程式碼,以使用針對受控識別建立的使用者:

備註

如果您使用Service Connector命令,請略過此步驟。

properties.put("user", "$AZ_POSTGRESQL_AD_MI_USERNAME");

進行這些程式碼變更後,您可以建置和重新部署應用程式。 然後,在瀏覽器中瀏覽至您的託管應用程式。 您的應用程式應該能夠成功連線到 PostgreSQL 資料庫。 角色分配可能需要幾分鐘才能在你的 Azure 環境中傳遞。 您的應用程式現在已設定為在本機和生產環境中執行,而開發人員不必管理應用程式本身中的密碼。

後續步驟

在本教學課程中,您瞭解如何將應用程式移轉至無密碼連線。

若想更深入探討本文討論的概念,請參閱以下資源: