你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

教程:通过服务连接器创建与数据库服务的无密码连接

无密码连接使用托管标识来访问 Azure 服务。 使用此方法,无需手动跟踪和管理托管标识的机密。 这些任务由 Azure 在内部安全地进行处理。

服务连接器可在 Azure Spring Apps、Azure 应用服务和 Azure 容器应用等应用托管服务中启用托管标识。 服务连接器还可将数据库服务(例如 Azure Database for PostgreSQL、Azure Database for MySQL 和 Azure SQL 数据库)配置为接受托管标识。

在本教程中,你将使用 Azure CLI 完成以下任务:

  • 使用 Azure CLI 检查初始环境。
  • 使用服务连接器创建无密码连接。
  • 使用服务连接器生成的环境变量或配置来访问数据库服务。

先决条件

设置你的环境

帐户

使用 Azure CLI 通过 az login 进行登录。 如果使用 Azure Cloud Shell 或已登录,请使用 az account show 确认你的帐户经过身份验证。

安装服务连接器无密码扩展

为 Azure CLI 安装服务连接器无密码扩展:

az extension add --name serviceconnector-passwordless --upgrade

创建无密码连接

接下来,我们将以 Azure 应用服务为例,使用托管标识来创建连接。

如果使用:

注意

如果使用 Azure 门户,请转到 Azure 应用服务Azure Spring AppsAzure 容器应用的“服务连接器”边栏选项卡,然后选择“创建”以创建连接。 Azure 门户将自动编写命令,并在 Cloud Shell 上触发命令执行。

以下 Azure CLI 命令使用 --client-type 参数。 运行 az webapp connection create postgres-flexible -h 以获取支持的客户端类型,并选择与应用程序匹配的客户端类型。

az webapp connection create postgres-flexible \
    --resource-group $RESOURCE_GROUP \
    --name $APPSERVICE_NAME \
    --target-resource-group $RESOURCE_GROUP \
    --server $POSTGRESQL_HOST \
    --database $DATABASE_NAME \
    --user-identity client-id=XX subs-id=XX \
    --client-type java

Azure Database for MySQL 灵活服务器需要用户分配的托管标识才能启用 Microsoft Entra 身份验证。 有关详细信息,请参阅设置 Azure Database for MySQL 灵活服务器的 Microsoft Entra 身份验证。 可以使用以下命令创建用户分配的托管标识:

USER_IDENTITY_NAME=<YOUR_USER_ASSIGNED_MANAGEMED_IDENTITY_NAME>
IDENTITY_RESOURCE_ID=$(az identity create \
    --name $USER_IDENTITY_NAME \
    --resource-group $RESOURCE_GROUP \
    --query id \
    --output tsv)

重要

创建用户分配的托管标识后,请让全局管理员或特权角色管理员为此标识授予以下权限:

  • User.Read.All
  • GroupMember.Read.All
  • Application.Read.All

有关详细信息,请参阅 Active Directory 身份验证权限部分。

接下来,使用服务连接器将应用连接到具有系统分配的托管标识的 MySQL 数据库。

以下 Azure CLI 命令使用 --client-type 参数。 运行 az webapp connection create mysql-flexible -h 以获取支持的客户端类型,并选择与应用程序匹配的客户端类型。

az webapp connection create mysql-flexible \
    --resource-group $RESOURCE_GROUP \
    --name $APPSERVICE_NAME \
    --target-resource-group $RESOURCE_GROUP \
    --server $MYSQL_HOST \
    --database $DATABASE_NAME \
    --user-identity client-id=XX subs-id=XX mysql-identity-id=$IDENTITY_RESOURCE_ID \
    --client-type java

以下 Azure CLI 命令使用 --client-type 参数。 运行 az webapp connection create sql -h 以获取支持的客户端类型,并选择与应用程序匹配的客户端类型。

az webapp connection create sql \
    --resource-group $RESOURCE_GROUP \
    --name $APPSERVICE_NAME \
    --target-resource-group $RESOURCE_GROUP \
    --server $SQL_HOST \
    --database $DATABASE_NAME \
    --user-identity client-id=XX subs-id=XX \
    --client-type dotnet

此服务连接器命令将在后台完成以下任务:

  • 启用系统分配的托管标识,或为 Azure 应用服务/Azure Spring Apps/Azure 容器应用托管的应用 $APPSERVICE_NAME 分配用户标识。
  • 将 Microsoft Entra 管理员设置为当前已登录用户。
  • 为系统分配的托管标识、用户分配的托管标识或服务主体添加数据库用户。 向此用户授予数据库 $DATABASE_NAME 的所有权限。 可以在上述命令输出的连接字符串中找到用户名。
  • 根据数据库类型将名为 AZURE_MYSQL_CONNECTIONSTRINGAZURE_POSTGRESQL_CONNECTIONSTRINGAZURE_SQL_CONNECTIONSTRING 的配置设置为 Azure 资源。
    • 对于应用服务,配置是在“应用设置”边栏选项卡中设置的。
    • 对于 Spring Apps,配置是在应用程序启动时设置的。
    • 对于容器应用,配置设置为环境变量。 可以在 Azure 门户的“服务连接器”边栏选项卡中获取所有配置及其值。

通过 Microsoft Entra 身份验证连接到数据库

创建连接后,可以使用应用程序中的连接字符串通过 Microsoft Entra 身份验证连接到数据库。 例如,可使用以下解决方案通过 Microsoft Entra 身份验证连接到数据库。

对于 .NET,没有用于支持无密码连接的插件或库。 可使用 Azure.Identity 等客户端库获取托管标识或服务主体的访问令牌。 然后,可使用访问令牌作为密码来连接到数据库。 使用下面的代码时,请对要使用的身份验证类型的代码片段的一部分取消评论。

using Azure.Identity;
using Azure.Core;
using Npgsql;

// Uncomment the following lines according to the authentication type.
// For system-assigned identity.
// var sqlServerTokenProvider = new DefaultAzureCredential();

// For user-assigned identity.
// var sqlServerTokenProvider = new DefaultAzureCredential(
//     new DefaultAzureCredentialOptions
//     {
//         ManagedIdentityClientId = Environment.GetEnvironmentVariable("AZURE_POSTGRESQL_CLIENTID");
//     }
// );

// For service principal.
// var tenantId = Environment.GetEnvironmentVariable("AZURE_POSTGRESQL_TENANTID");
// var clientId = Environment.GetEnvironmentVariable("AZURE_POSTGRESQL_CLIENTID");
// var clientSecret = Environment.GetEnvironmentVariable("AZURE_POSTGRESQL_CLIENTSECRET");
// var sqlServerTokenProvider = new ClientSecretCredential(tenantId, clientId, clientSecret);

// Acquire the access token. 
AccessToken accessToken = await sqlServerTokenProvider.GetTokenAsync(
    new TokenRequestContext(scopes: new string[]
    {
        "https://ossrdbms-aad.database.windows.net/.default"
    }));

// Combine the token with the connection string from the environment variables provided by Service Connector.
string connectionString =
    $"{Environment.GetEnvironmentVariable("AZURE_POSTGRESQL_CONNECTIONSTRING")};Password={accessToken.Token}";

// Establish the connection.
using (var connection = new NpgsqlConnection(connectionString))
{
    Console.WriteLine("Opening connection using access token...");
    connection.Open();
}

接下来,如果你在使用服务连接器之前已经在 PostgreSQL 灵活服务器中创建了表和序列,则你需要以所有者身份进行连接,并向服务连接器创建的 <aad-username> 授予权限。 服务连接器设置的连接字符串或配置中的用户名应类似于 aad_<connection name>。 如果使用 Azure 门户,请选择 Service Type 列旁边的展开按钮并获取值。 如果使用 Azure CLI,请检查 CLI 命令输出中的 configurations

然后,执行用于授予权限的查询。

az extension add --name rdbms-connect

az postgres flexible-server execute -n <postgres-name> -u <owner-username> -p "<owner-password>" -d <database-name> --querytext "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO \"<aad-username>\";GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO \"<aad username>\";"

<owner-username><owner-password> 是现有表的所有者,可以向他人授予权限。 <aad-username> 是由服务连接器创建的用户。 将其替换为实际值。

通过此命令验证结果:

az postgres flexible-server execute -n <postgres-name> -u <owner-username> -p "<owner-password>" -d <database-name> --querytext "SELECT distinct(table_name) FROM information_schema.table_privileges WHERE grantee='<aad-username>' AND table_schema='public';" --output table

对于 .NET,没有用于支持无密码连接的插件或库。 可使用 Azure.Identity 等客户端库获取托管标识或服务主体的访问令牌。 然后,可使用访问令牌作为密码来连接到数据库。 使用下面的代码时,请对要使用的身份验证类型的代码片段的一部分取消评论。

using Azure.Core;
using Azure.Identity;
using MySqlConnector;

// Uncomment the following lines according to the authentication type.
// For system-assigned managed identity.
// var credential = new DefaultAzureCredential();

// For user-assigned managed identity.
// var credential = new DefaultAzureCredential(
//     new DefaultAzureCredentialOptions
//     {
//         ManagedIdentityClientId = Environment.GetEnvironmentVariable("AZURE_MYSQL_CLIENTID");
//     });

// For service principal.
// var tenantId = Environment.GetEnvironmentVariable("AZURE_MYSQL_TENANTID");
// var clientId = Environment.GetEnvironmentVariable("AZURE_MYSQL_CLIENTID");
// var clientSecret = Environment.GetEnvironmentVariable("AZURE_MYSQL_CLIENTSECRET");
// var credential = new ClientSecretCredential(tenantId, clientId, clientSecret);

var tokenRequestContext = new TokenRequestContext(
    new[] { "https://ossrdbms-aad.database.windows.net/.default" });
AccessToken accessToken = await credential.GetTokenAsync(tokenRequestContext);
// Open a connection to the MySQL server using the access token.
string connectionString =
    $"{Environment.GetEnvironmentVariable("AZURE_MYSQL_CONNECTIONSTRING")};Password={accessToken.Token}";

using var connection = new MySqlConnection(connectionString);
Console.WriteLine("Opening connection using access token...");
await connection.OpenAsync();

// do something

有关更多代码示例,请参阅使用托管标识从应用服务连接到 Azure 数据库,而无需使用密钥

  1. 安装依赖项。

    dotnet add package Microsoft.Data.SqlClient
    
  2. 从服务连接器添加的环境变量中获取 Azure SQL 数据库连接字符串。

    using Microsoft.Data.SqlClient;
    
    string connectionString = 
        Environment.GetEnvironmentVariable("AZURE_SQL_CONNECTIONSTRING")!;
    
    using var connection = new SqlConnection(connectionString);
    connection.Open();
    

    有关详细信息,请参阅使用 Active Directory 托管标识身份验证

有关详细信息,请参阅 Microsoft SQL Server 客户端编程的主页

将应用程序部署到 Azure 托管服务

最后,将应用程序部署到 Azure 托管服务。 该源服务可以使用托管标识连接到 Azure 上的目标数据库。

对于 Azure 应用服务,可以通过 az webapp deploy 命令部署应用程序代码。 有关详细信息,请参阅快速入门:部署 ASP.NET Web 应用

然后,可以检查日志或调用应用程序以查看它是否可以成功连接到 Azure 数据库。

疑难解答

权限

如果遇到任何与权限相关的错误,请使用命令 az account show 确认 Azure CLI 已登录用户。 确保使用正确的帐户进行登录。 接下来,确认你拥有使用服务连接器创建无密码连接可能需要的以下权限。

权限 操作
Microsoft.DBforPostgreSQL/flexibleServers/read 需要此权限才能获取数据库服务器信息
Microsoft.DBforPostgreSQL/flexibleServers/write 需要此权限才能为数据库服务器启用 Microsoft Entra 身份验证
Microsoft.DBforPostgreSQL/flexibleServers/firewallRules/write 需要此权限才能创建防火墙规则以防本地 IP 地址被阻止
Microsoft.DBforPostgreSQL/flexibleServers/firewallRules/delete 需要此权限才能还原服务连接器创建的防火墙规则以避免安全问题
Microsoft.DBforPostgreSQL/flexibleServers/administrators/read 需要此权限才能检查 Azure CLI 登录用户是否为数据库服务器 Microsoft Entra 管理员
Microsoft.DBforPostgreSQL/flexibleServers/administrators/write 需要此权限才能将 Azure CLI 登录用户添加为数据库服务器 Microsoft Entra 管理员
权限 操作
Microsoft.DBforMySQL/flexibleServers/read 需要此权限才能获取数据库服务器信息
Microsoft.DBforMySQL/flexibleServers/write 需要此权限才能将所提供的用户分配的托管标识添加到数据库服务器
Microsoft.DBforMySQL/flexibleServers/firewallRules/write 需要此权限才能创建防火墙规则以防本地 IP 地址被阻止
Microsoft.DBforMySQL/flexibleServers/firewallRules/delete 需要此权限才能还原服务连接器创建的防火墙规则以避免安全问题
Microsoft.DBforMySQL/flexibleServers/administrators/read 需要此权限才能检查 Azure CLI 登录用户是否为数据库服务器 Microsoft Entra 管理员
Microsoft.DBforMySQL/flexibleServers/administrators/write 需要此权限才能将 Azure CLI 登录用户添加为数据库服务器 Microsoft Entra 管理员
权限 操作
Microsoft.Sql/servers/read 需要此权限才能获取数据库服务器信息
Microsoft.Sql/servers/firewallRules/write 需要此权限才能创建防火墙规则以防本地 IP 地址被阻止
Microsoft.Sql/servers/firewallRules/delete 需要此权限才能还原服务连接器创建的防火墙规则以避免安全问题
Microsoft.Sql/servers/administrators/read 需要此权限才能检查 Azure CLI 登录用户是否为数据库服务器 Microsoft Entra 管理员
Microsoft.Sql/servers/administrators/write 需要此权限才能将 Azure CLI 登录用户添加为数据库服务器 Microsoft Entra 管理员

在某些情况下,不需要权限。 例如,如果经过 Azure CLI 身份验证的用户已经是 SQL Server 上的 Active Directory 管理员,则无需具有 Microsoft.Sql/servers/administrators/write 权限。

Microsoft Entra ID

如果收到 ERROR: AADSTS530003: Your device is required to be managed to access this resource. 错误,请向 IT 部门寻求将此设备加入 Microsoft Entra ID 的帮助。 有关详细信息,请参阅已建立 Microsoft Entra 联接的设备

服务连接器需要访问 Microsoft Entra ID 才能获取帐户的信息以及托管服务的托管标识。 可使用以下命令检查设备是否能够访问 Microsoft Entra ID:

az ad signed-in-user show

如果无法以交互方式登录,你可能还会收到错误和 Interactive authentication is needed。 若要解决此错误,请使用 az login 命令进行登录。

网络连接

如果数据库服务器位于虚拟网络中,请确保运行 Azure CLI 命令的环境可以访问虚拟网络中的服务器。

如果数据库服务器位于虚拟网络中,请确保运行 Azure CLI 命令的环境可以访问虚拟网络中的服务器。

如果数据库服务器不允许公共访问,请确保运行 Azure CLI 命令的环境可以通过专用终结点访问服务器。

后续步骤

有关服务连接器和无密码连接的详细信息,请参阅以下资源: