可以使用系统分配的托管标识和用户分配的托管标识向 Azure Database for PostgreSQL 灵活服务器进行身份验证。 本文介绍如何使用 Azure 虚拟机(VM)的系统分配托管标识来访问 Azure Database for PostgreSQL 灵活服务器实例。 托管标识由 Azure 自动管理,使你能够向支持 Microsoft Entra 身份验证的服务进行身份验证,而无需在代码中插入凭据。
您将了解如何执行以下操作:
- 授予 VM 对 Azure Database for PostgreSQL 灵活服务器实例的访问权限。
- 在数据库中创建表示 VM 的系统分配标识的用户。
- 使用 VM 标识获取访问令牌,并使用它查询 Azure Database for PostgreSQL 灵活服务器实例。
- 在 C# 示例应用程序中实现令牌检索。
先决条件
- 如果不熟悉 Azure 资源功能的托管标识,请参阅此概述。 如果没有 Azure 帐户,请在继续之前 注册试用帐户 。
- 若要执行所需的资源创建和角色管理,帐户需要相应范围(订阅或资源组)的“所有者”权限。 如需角色分配方面的帮助,请参阅 “分配 Azure 角色”来管理对 Azure 订阅资源的访问权限。
- 需要一个 Azure VM(例如,运行 Ubuntu Linux),该 VM 用于使用托管标识访问数据库
- 需要配置 了 Microsoft Entra 身份验证的 Azure Database for PostgreSQL 灵活服务器实例
- 若要遵循 C# 示例,请先完成有关如何使用 C# 进行连接的指南
为 VM 创建系统分配的托管标识
通过命令使用 az vm identity assignidentity assign
,可将系统分配的标识用于现有 VM:
az vm identity assign -g myResourceGroup -n myVm
检索系统分配的托管标识的应用程序 ID,在后续几个步骤中需要:
# Get the client ID (application ID) of the system-assigned managed identity
az ad sp list --display-name vm-name --query [*].appId --out tsv
为托管标识创建 Azure Database for PostgreSQL 灵活服务器用户
现在,以 Microsoft Entra 管理员用户身份连接到 Azure Database for PostgreSQL 灵活服务器数据库,并运行以下 SQL 语句,替换为 <identity_name>
为其创建了系统分配的托管标识的资源的名称:
请注意 ,必须在 Postgres 数据库上运行pgaadauth_create_principal。
select * from pgaadauth_create_principal('<identity_name>', false, false);
成功如下所示:
pgaadauth_create_principal
-----------------------------------
Created role for "<identity_name>"
(1 row)
有关管理已启用 entra ID 的数据库角色Microsoft的详细信息,请参阅 如何管理已启用 Entra ID 的 Azure Database for PostgreSQL 灵活服务器角色Microsoft
使用标识名称作为角色名称和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.chinacloudapi.cn
-
client_id
=CLIENT_ID
(之前检索到的)
返回包含字段的 access_token
JSON 结果 - 此长文本值是连接到数据库时应用作密码的托管标识访问令牌。
出于测试目的,可以在 shell 中运行以下命令。
注释
请注意,curl
需要jq
安装客户端psql
。
# 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.chinacloudapi.cn&client_id=CLIENT_ID' -H Metadata:true | jq -r .access_token`
# Connect to the database
psql -h SERVER --user USER DBNAME
现在已连接到前面配置的数据库。
使用托管标识进行连接
本部分介绍如何使用 VM 的用户分配的托管标识获取访问令牌,并使用它调用 Azure Database for PostgreSQL 灵活服务器。 Azure Database for PostgreSQL 灵活服务器原生支持Microsoft Entra 身份验证,因此可以直接接受使用 Azure 资源的托管标识获取的访问令牌。 创建与 Azure Database for PostgreSQL 灵活服务器的连接时,请在密码字段中传递访问令牌。
在 Python 中使用托管标识进行连接
有关 Python 代码示例,请参阅 快速入门:使用 Python 连接和查询 Azure Database for PostgreSQL 灵活服务器中的数据
在 Java 中使用托管标识进行连接
有关 Java 代码示例,请参阅 快速入门:将 Java 和 JDBC 与 Azure Database for PostgreSQL 灵活服务器配合使用
在 C 中使用托管标识进行连接#
下面是使用访问令牌打开与 Azure Database for PostgreSQL 灵活服务器的连接的 .NET 代码示例。 此代码必须在 VM 上运行,才能使用系统分配的托管标识从 Microsoft Entra ID 获取访问令牌。 将 HOST、USER(替换为 <identity_name>
)和 DATABASE
的值。
using Azure.Identity;
using Npgsql;
using System;
class Program
{
static void Main(string[] args)
{
try
{
// Obtain an access token using the system-assigned managed identity
var tokenCredential = new DefaultAzureCredential();
var accessToken = tokenCredential.GetToken(
new Azure.Core.TokenRequestContext(new[] { "https://ossrdbms-aad.database.chinacloudapi.cn/.default" })
);
// Build the connection string
string host = "your-server-name.postgres.database.chinacloudapi.cn"; // Replace with your flexible server's host
string database = "your-database-name"; // Replace with your database name
string user = "<identity_name>"; // Replace with your identity name (e.g., "myManagedIdentity")
var connectionString = $"Host={host};Database={database};Username={user};Password={accessToken.Token};SSL Mode=Require;Trust Server Certificate=true";
// Open a connection to the database
using var connection = new NpgsqlConnection(connectionString);
connection.Open();
Console.WriteLine("Connection successful!");
// Optional: Perform a simple query
using var command = new NpgsqlCommand("SELECT version();", connection);
using var reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine($"PostgreSQL version: {reader.GetString(0)}");
}
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred: {ex.Message}");
}
}
}
必须填写以下占位符:
- 主机:将 your-server-name.postgres.database.chinacloudapi.cn 替换为灵活服务器的主机名。
- USER:将identity_name<替换为>托管标识的名称。
-
DATABASE
:将 your-database-name 替换为 Azure Database for PostgreSQL 实例的名称。 - Microsoft Entra 身份验证:代码使用 VM 的系统分配托管标识从 Microsoft Entra ID 中提取访问令牌。
运行时,此命令提供如下所示的输出:
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