Share via


使用受控識別 連線 適用於 PostgreSQL 的 Azure 資料庫 - 彈性伺服器

適用範圍:適用於 PostgreSQL 的 Azure 資料庫 - 彈性伺服器

您可以使用系統指派和使用者指派的受控識別來驗證 適用於 PostgreSQL 的 Azure 資料庫 彈性伺服器。 本文說明如何使用系統指派的受控識別,讓 Azure 虛擬機 (VM) 存取 適用於 PostgreSQL 的 Azure 資料庫 彈性伺服器實例。 受控識別會自動由 Azure 管理,並可讓您向支援 Microsoft Entra 驗證的服務進行驗證,而不需要將認證插入您的程式碼。

您將學習如何:

  • 將您的 VM 存取權授與 適用於 PostgreSQL 的 Azure 資料庫 彈性伺服器實例。
  • 在資料庫中建立代表 VM 系統指派身分識別的使用者。
  • 使用 VM 身分識別取得存取令牌,並用它來查詢 適用於 PostgreSQL 的 Azure 資料庫 彈性伺服器實例。
  • 在 C# 範例應用程式中實作令牌擷取。

必要條件

  • 如果您不熟悉 Azure 資源的受控識別功能,請參閱此 概觀。 如果您沒有 Azure 帳戶, 請先註冊免費帳戶 ,再繼續進行。
  • 若要執行必要的資源建立和角色管理,您的帳戶需要適當範圍(您的訂用帳戶或資源群組)的「擁有者」許可權。 如果您需要角色指派的協助,請參閱 指派 Azure 角色來管理 Azure 訂用帳戶資源的存取權。
  • 您需要 Azure VM(例如,執行 Ubuntu Linux),您想要用來使用受控識別來存取資料庫
  • 您需要 適用於 PostgreSQL 的 Azure 資料庫 已設定 Microsoft Entra 驗證的彈性伺服器實例
  • 若要遵循 C# 範例,請先完成如何使用 C 連線 指南#

為您的 VM 建立系統指派的受控識別

使用 az vm identity assign 搭配 identity assign 命令,可將系統指派的身分識別啟用至現有的 VM:

az vm identity assign -g myResourceGroup -n myVm

擷取系統指派受控識別的應用程式標識碼,後續幾個步驟中將需要此標識碼:

# Get the client ID (application ID) of the system-assigned managed identity

az ad sp list --display-name vm-name --query [*].appId --out tsv

為受控識別建立 適用於 PostgreSQL 的 Azure 資料庫 彈性伺服器使用者

現在,以 Microsoft Entra 系統管理員使用者身分連線到您的 適用於 PostgreSQL 的 Azure 資料庫 彈性伺服器資料庫,然後執行下列 SQL 語句,並將 取代<identity_name>為您建立系統指派受控識別的資源名稱:

請注意 ,pgaadauth_create_principal 必須在Postgres資料庫上執行。

select * from pgaadauth_create_principal('<identity_name>', false, false);

成功看起來如下:

    pgaadauth_create_principal
-----------------------------------
 Created role for "<identity_name>"
(1 row)

如需管理已啟用 Microsoft Entra ID 的資料庫角色的詳細資訊,請參閱如何管理已啟用 Microsoft Entra 識別碼 適用於 PostgreSQL 的 Azure 資料庫 - 彈性伺服器角色

當以身分識別名稱做為角色名稱和 Microsoft Entra 令牌作為密碼進行驗證時,受控識別現在具有存取權。

注意

如果受控識別無效,則會傳回錯誤: ERROR: Could not validate AAD user <ObjectId> because its name is not found in the tenant. [...]

注意

如果您看到「沒有函式相符...」之類的錯誤,請確定您正在連線到 postgres 資料庫,而不是您也建立的不同資料庫。

從 Azure 實體數據服務擷取存取令牌

您的應用程式現在可以從 Azure 實例元數據服務擷取存取令牌,並使用它向資料庫進行驗證。

此令牌擷取是透過向 HTTP 要求, http://169.254.169.254/metadata/identity/oauth2/token 並傳遞下列參數來完成:

  • api-version = 2018-02-01
  • resource = https://ossrdbms-aad.database.windows.net
  • client_id = CLIENT_ID (您稍早擷取的)

您會傳回包含欄位的 access_token JSON 結果 - 這個長文字值是連線到資料庫時應該用來做為密碼的受控識別存取令牌。

為了進行測試,您可以在殼層中執行下列命令。

注意

請注意,您需要 curl安裝、 jqpsql 用戶端。

# Retrieve the access token

export PGPASSWORD=`curl -s 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fossrdbms-aad.database.windows.net&client_id=CLIENT_ID' -H Metadata:true | jq -r .access_token`

# Connect to the database

psql -h SERVER --user USER DBNAME

您現在已連線到您稍早設定的資料庫。

在 C 中使用受控識別 連線#

本節說明如何使用 VM 的使用者指派受控識別來取得存取令牌,並用它來呼叫 適用於 PostgreSQL 的 Azure 資料庫 彈性伺服器。 適用於 PostgreSQL 的 Azure 資料庫 彈性伺服器原生支援 Microsoft Entra 驗證,因此可以直接接受使用 Azure 資源的受控識別取得的存取令牌。 建立與 適用於 PostgreSQL 的 Azure 資料庫 彈性伺服器的連線時,您會在 [密碼] 字段中傳遞存取令牌。

以下是使用存取令牌開啟 適用於 PostgreSQL 的 Azure 資料庫 彈性伺服器連線的 .NET 程式代碼範例。 此程式代碼必須在 VM 上執行,才能使用系統指派的受控識別,從 Microsoft Entra ID 取得存取令牌。 以、 和 DATABASE 取代 HOST、USER (with <identity_name>) 和 DATABASE 的值。

using System;
using System.Net;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
using Npgsql;
using Azure.Identity;

namespace Driver
{
    class Script
    {
        // Obtain connection string information from the portal for use in the following variables
        private static string Host = "HOST";
        private static string User = "USER";
        private static string Database = "DATABASE";

        static async Task Main(string[] args)
        {
            //
            // Get an access token for PostgreSQL.
            //
            Console.Out.WriteLine("Getting access token from Azure AD...");

            // Azure AD resource ID for Azure Database for PostgreSQL Flexible Server is https://ossrdbms-aad.database.windows.net/
            string accessToken = null;

            try
            {
                // Call managed identities for Azure resources endpoint.
                var sqlServerTokenProvider = new DefaultAzureCredential();
                accessToken = (await sqlServerTokenProvider.GetTokenAsync(
                    new Azure.Core.TokenRequestContext(scopes: new string[] { "https://ossrdbms-aad.database.windows.net/.default" }) { })).Token;

            }
            catch (Exception e)
            {
                Console.Out.WriteLine("{0} \n\n{1}", e.Message, e.InnerException != null ? e.InnerException.Message : "Acquire token failed");
                System.Environment.Exit(1);
            }

            //
            // Open a connection to the PostgreSQL server using the access token.
            //
            string connString =
                String.Format(
                    "Server={0}; User Id={1}; Database={2}; Port={3}; Password={4}; SSLMode=Prefer",
                    Host,
                    User,
                    Database,
                    5432,
                    accessToken);

            using (var conn = new NpgsqlConnection(connString))
            {
                Console.Out.WriteLine("Opening connection using access token...");
                conn.Open();

                using (var command = new NpgsqlCommand("SELECT version()", conn))
                {

                    var reader = command.ExecuteReader();
                    while (reader.Read())
                    {
                        Console.WriteLine("\nConnected!\n\nPostgres version: {0}", reader.GetString(0));
                    }
                }
            }
        }
    }
}

執行時,此命令會提供如下的輸出:

Getting access token from Azure AD...
Opening connection using access token...

Connected!

Postgres version: PostgreSQL 11.11, compiled by Visual C++ build 1800, 64-bit

下一步

  • 使用 適用於 PostgreSQL 的 Azure 資料庫 檢閱 Microsoft Entra 驗證的整體概念 - 彈性伺服器