你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
若要对Azure服务进行身份验证的最佳方法是使用 托管标识,但在某些情况下,情况并非如此。 在这些情况下,使用访问密钥或机密。 应定期轮换访问密钥或机密。
本教程介绍如何为使用一组身份验证凭据的数据库和服务自动轮换机密。 有关不同资产类型的自动轮换概念及其优势的全面概述,请参阅 Azure 密钥保管库 中对自动轮换的了解。
具体而言,本教程使用由Azure 事件网格通知触发的函数轮换存储在Azure 密钥保管库中的SQL Server密码:
- 在机密到期日期之前的三十天,密钥保管库将“即将过期”事件发布到事件网格。
- 事件网格会检查事件订阅,并使用 HTTP POST 调用已订阅该事件的函数应用终结点。
- 函数应用接收机密信息,生成新的随机密码,并在密钥保管库中使用新密码为机密创建新版本。
- 函数应用使用新密码更新SQL Server。
注释
步骤 3 和步骤 4 之间可能存在延迟。 在此期间,密钥保管库中的机密将无法对SQL Server进行身份验证。 如果任一步骤失败,事件网格会重试两个小时。
先决条件
- Azure订阅 - 免费创建一个订阅。
- Azure 密钥保管库
- SQL Server
如果没有现有的密钥保管库和SQL Server,则可以使用此部署链接:
- 在“资源组”下,选择“新建”。 为组命名,我们将在本教程中使用 akvrotation 。
- 在 “SQL 管理员登录名”下,键入 SQL 管理员登录名。
- 选择“查看 + 创建”。
- 选择 创建
现在,你将有一个密钥保管库和一个SQL Server实例。 可以通过运行以下命令在Azure CLI中验证此设置:
az resource list -o table -g akvrotation
结果类似于以下输出:
Name ResourceGroup Location Type Status
----------------------- -------------------- ---------- --------------------------------- --------
akvrotation-kv akvrotation eastus Microsoft.KeyVault/vaults
akvrotation-sql akvrotation eastus Microsoft.Sql/servers
akvrotation-sql/master akvrotation eastus Microsoft.Sql/servers/databases
akvrotation-sql2 akvrotation eastus Microsoft.Sql/servers
akvrotation-sql2/master akvrotation eastus Microsoft.Sql/servers/databases
创建和部署 SQL Server 密码轮换函数
重要
此模板要求密钥保管库、SQL Server 和 Azure 函数位于同一资源组中。
接下来,创建具有系统托管标识的函数应用,以及其他必需的组件,并部署 SQL Server 密码轮换函数
函数应用需要以下组件:
- Azure 应用服务 计划
- 带有SQL密码轮换功能以及事件触发器和HTTP触发器的Function App
- 进行函数应用触发器管理时所需的存储帐户
- 用于函数应用标识访问 密钥保管库 中机密的 Azure RBAC 角色分配
- “SecretNearExpiry”事件的事件网格事件订阅
选择Azure模板部署链接:
在 资源组 列表中,选择 akvrotation。
在 SQL Server Name 中,输入要旋转密钥的 SQL Server 名称和密码。
在 密钥保管库 Name中,键入key vault名称
在 函数应用名称中,键入函数应用名称
在 机密名称中,键入将存储密码的机密名称
在 Repo Url 中,键入函数代码GitHub位置(https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp.git)
选择“查看 + 创建”。
选择 创建。
完成上述步骤后,你将拥有存储帐户、服务器场和函数应用。 可以通过运行以下命令在Azure CLI中验证此设置:
az resource list -o table -g akvrotation
结果将类似于以下输出:
Name ResourceGroup Location Type Status
----------------------- -------------------- ---------- --------------------------------- --------
akvrotation-kv akvrotation eastus Microsoft.KeyVault/vaults
akvrotation-sql akvrotation eastus Microsoft.Sql/servers
akvrotation-sql/master akvrotation eastus Microsoft.Sql/servers/databases
cfogyydrufs5wazfunctions akvrotation eastus Microsoft.Storage/storageAccounts
akvrotation-fnapp akvrotation eastus Microsoft.Web/serverFarms
akvrotation-fnapp akvrotation eastus Microsoft.Web/sites
akvrotation-fnapp akvrotation eastus Microsoft.insights/components
有关如何创建函数应用并使用托管标识访问 密钥保管库 的信息,请参阅 从 Azure 门户创建函数应用、如何为应用服务和 Azure Functions 使用托管标识,以及 使用 Azure RBAC 为 密钥保管库 提供访问权限。
旋转函数
在先前步骤中部署的函数使用事件通过更新 密钥保管库 和 SQL 数据库来触发机密轮替。
函数触发器事件
此函数读取事件数据并运行旋转逻辑:
public static class SimpleRotationEventHandler
{
[FunctionName("AKVSQLRotation")]
public static void Run([EventGridTrigger]EventGridEvent eventGridEvent, ILogger log)
{
log.LogInformation("C# Event trigger function processed a request.");
var secretName = eventGridEvent.Subject;
var secretVersion = Regex.Match(eventGridEvent.Data.ToString(), "Version\":\"([a-z0-9]*)").Groups[1].ToString();
var keyVaultName = Regex.Match(eventGridEvent.Topic, ".vaults.(.*)").Groups[1].ToString();
log.LogInformation($"Key Vault Name: {keyVaultName}");
log.LogInformation($"Secret Name: {secretName}");
log.LogInformation($"Secret Version: {secretVersion}");
SecretRotator.RotateSecret(log, secretName, keyVaultName);
}
}
机密轮换逻辑
此轮换方法从机密中读取数据库信息,创建新版本的机密,并使用新机密更新数据库:
public class SecretRotator
{
private const string CredentialIdTag = "CredentialId";
private const string ProviderAddressTag = "ProviderAddress";
private const string ValidityPeriodDaysTag = "ValidityPeriodDays";
public static void RotateSecret(ILogger log, string secretName, string keyVaultName)
{
//Retrieve Current Secret
var kvUri = "https://" + keyVaultName + ".vault.azure.net";
var client = new SecretClient(new Uri(kvUri), new DefaultAzureCredential());
KeyVaultSecret secret = client.GetSecret(secretName);
log.LogInformation("Secret Info Retrieved");
//Retrieve Secret Info
var credentialId = secret.Properties.Tags.ContainsKey(CredentialIdTag) ? secret.Properties.Tags[CredentialIdTag] : "";
var providerAddress = secret.Properties.Tags.ContainsKey(ProviderAddressTag) ? secret.Properties.Tags[ProviderAddressTag] : "";
var validityPeriodDays = secret.Properties.Tags.ContainsKey(ValidityPeriodDaysTag) ? secret.Properties.Tags[ValidityPeriodDaysTag] : "";
log.LogInformation($"Provider Address: {providerAddress}");
log.LogInformation($"Credential Id: {credentialId}");
//Check Service Provider connection
CheckServiceConnection(secret);
log.LogInformation("Service Connection Validated");
//Create new password
var randomPassword = CreateRandomPassword();
log.LogInformation("New Password Generated");
//Add secret version with new password to Key Vault
CreateNewSecretVersion(client, secret, randomPassword);
log.LogInformation("New Secret Version Generated");
//Update Service Provider with new password
UpdateServicePassword(secret, randomPassword);
log.LogInformation("Password Changed");
log.LogInformation($"Secret Rotated Successfully");
}
}
可以在 GitHub 上找到完整的代码。
将机密添加到密钥保管库
设置访问策略以向用户授予 管理机密 权限:
az role assignment create --role "Key Vault Secrets Officer" --assignee <email-address-of-user> --scope /subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.KeyVault/vaults/akvrotation-kv
创建一个包含标签的新密码,其中包含 SQL Server 资源 ID、SQL Server 登录名,以及密码的有效期(以天为单位)。 提供 SQL 数据库中的机密名称、初始密码(在我们的示例中为“Simple123”),并包括明天设置的到期日期。
$tomorrowDate = (get-date).AddDays(+1).ToString("yyyy-MM-ddThh:mm:ssZ")
az keyvault secret set --name sqlPassword --vault-name akvrotation-kv --value "Simple123" --tags "CredentialId=sqlAdmin" "ProviderAddress=<sql-database-resource-id>" "ValidityPeriodDays=90" --expires $tomorrowDate
创建到期日期较短的机密将在 15 分钟内发布 SecretNearExpiry 事件,这反过来会触发函数轮换机密。
测试和验证
若要验证机密是否已轮换,请转到 密钥保管库>Secrets:
打开 sqlPassword 机密并查看原始版本和旋转版本:
创建 Web 应用
若要验证 SQL 凭据,请创建 Web 应用。 此 Web 应用将从密钥保管库获取机密,从机密中提取 SQL 数据库信息和凭据,并测试与SQL Server的连接。
Web 应用需要以下组件:
- 一个使用系统托管标识的 Web 应用
- 访问策略,用于通过 Web 应用托管标识访问密钥保管库中的机密
选择Azure模板部署链接:
选择 akvrotation 资源组。
在“SQL Server 名称”中,键入密码需进行轮替的 SQL Server 名称
在 密钥保管库 Name中,键入key vault名称
在 机密名称中,键入存储密码的机密名称
在 Repo Url 中,键入 web 应用代码GitHub位置(https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp-WebApp.git)
选择“查看 + 创建”。
选择 创建。
打开 Web 应用
转到已部署的应用程序 URL:
“https://akvrotation-app.azurewebsites.net/”
当应用程序在浏览器中打开时,你将看到 “生成的机密值 ”和“ 数据库连接 ”值 true。
使用 AI 自定义数据库的旋转函数
本教程演示SQL Server的机密轮换,但你可以针对其他数据库类型调整轮换函数。 VS Code 中的GitHub Copilot可帮助你修改轮换函数代码以使用特定的数据库或凭据类型。
I'm using the Azure Key Vault secret rotation tutorial for SQL Server. Help me modify the rotation function to work with PostgreSQL instead. The function should:
1. Generate a new secure password
2. Update the PostgreSQL database user password
3. Store the new password in Key Vault
Show me the changes needed to the C# function code, including the correct PostgreSQL connection library and password update command.
Copilot还有助于为其他凭据类型(如 API 密钥、连接字符串或服务帐户密码)调整此模式。
GitHub Copilot由 AI 提供支持,因此可能会带来惊喜和错误。 有关详细信息,请参阅 Copilot 常见问题解答。
了解详细信息
- 使用两组凭据进行资源轮换
- 理解 Azure 密钥保管库 中的自动轮换
- 监控 密钥保管库 使用 Azure 事件网格
- 密钥保管库机密更改时接收电子邮件
- Azure 事件网格 事件架构 for Azure 密钥保管库