编程 为什么 Azure 托管身份取代了存储的凭据:以及 2026 年如何使用它

2026-09-06 03:11:19

为什么 Azure 托管身份取代了存储的凭据:以及 2026 年如何使用它

一位开发者在 Dev.to 上发表文章,详细介绍了 Azure 托管身份(Managed Identity)如何取代传统的存储凭据方式,以及在 2026 年如何正确使用它。文章指出,每个 Azure 项目最终都会面临同一个问题:连接字符串存在哪里?而托管身份提供了一个更安全、更易维护的解决方案。

背景:存储凭据的问题

在 Azure 项目中,几乎每个开发者都会遇到这样的对话:

"连接字符串存在哪里?"
"存在配置文件里。"
"那配置文件会提交到 Git 吗?"
"不会,我们用环境变量。"
"那环境变量在 CI/CD 里怎么设置?"
"存在密钥管理服务里。"
"那密钥管理服务的访问密钥存在哪里?"

这个无限循环的问题,本质上是凭据管理的困境:无论你把凭据存在哪里,都需要另一个凭据来访问它,形成"鸡生蛋"的问题。

传统存储凭据的问题

  1. 安全风险

    • 凭据可能被意外提交到代码仓库
    • 配置文件可能被未授权访问
    • 日志和错误信息可能泄露凭据
    • 人员离职后凭据可能未及时轮换
  2. 管理复杂性

    • 需要管理多个环境的凭据(开发、测试、生产)
    • 凭据轮换需要更新多个地方
    • 缺乏统一的凭据生命周期管理
    • 审计和合规困难
  3. 运维负担

    • 凭据过期导致服务中断
    • 紧急轮换凭据需要修改配置和重启服务
    • 不同服务的凭据管理方式不一致
    • 缺乏自动化的凭据轮换机制

什么是 Azure 托管身份

Azure 托管身份(Managed Identity)是 Azure Active Directory(Azure AD)提供的一项功能,它为 Azure 资源自动管理身份凭据,开发者不需要存储或管理任何密钥

核心原理

托管身份的核心原理是:

  1. Azure 为资源(如虚拟机、App Service、函数应用等)自动创建一个 Azure AD 身份
  2. 这个身份的凭据由 Azure 自动管理和轮换
  3. 应用程序可以通过 Azure Instance Metadata Service(IMDS)获取访问令牌
  4. 使用访问令牌向支持 Azure AD 认证的服务(如 Key Vault、Storage、SQL Database 等)进行认证

关键优势

  1. 无需存储凭据:应用程序中没有任何密钥或连接字符串
  2. 自动轮换:Azure 自动轮换凭据,无需人工干预
  3. 细粒度访问控制:通过 Azure RBAC 精确控制身份的权限
  4. 统一管理:所有资源的身份管理方式一致
  5. 审计日志:所有身份的操作都有审计记录
  6. 零信任架构:符合零信任安全模型的要求

托管身份的类型

Azure 提供两种类型的托管身份:

类型特点适用场景
系统分配的托管身份与资源生命周期绑定,资源删除时身份也删除单个资源需要独立身份
用户分配的托管身份独立的 Azure 资源,可以分配给多个资源多个资源共享同一身份,或需要预创建身份

托管身份如何取代存储凭据

传统方式 vs 托管身份方式

传统方式

应用程序 → 读取配置文件中的连接字符串 → 使用连接字符串访问数据库

问题:连接字符串需要存储在某个地方,存在泄露风险。

托管身份方式

应用程序 → 通过 IMDS 获取 Azure AD 访问令牌 → 使用令牌访问数据库

优势:不需要存储任何凭据,令牌由 Azure 自动管理。

具体场景对比

场景一:访问 Azure Key Vault

传统方式

# 需要存储访问 Key Vault 的凭据
from azure.keyvault.secrets import SecretClient
from azure.identity import ClientSecretCredential

credential = ClientSecretCredential(
    tenant_id=os.environ["AZURE_TENANT_ID"],
    client_id=os.environ["AZURE_CLIENT_ID"],
    client_secret=os.environ["AZURE_CLIENT_SECRET"]  # 这个密钥存在哪里?
)
client = SecretClient(vault_url="https://myvault.vault.azure.net", credential=credential)
secret = client.get_secret("my-secret")

托管身份方式

# 不需要任何凭据
from azure.keyvault.secrets import SecretClient
from azure.identity import DefaultAzureCredential

credential = DefaultAzureCredential()  # 自动使用托管身份
client = SecretClient(vault_url="https://myvault.vault.azure.net", credential=credential)
secret = client.get_secret("my-secret")

场景二:访问 Azure Storage

传统方式

# 使用连接字符串
from azure.storage.blob import BlobServiceClient

connect_str = os.environ["AZURE_STORAGE_CONNECTION_STRING"]  # 包含账户密钥
blob_service_client = BlobServiceClient.from_connection_string(connect_str)

托管身份方式

# 使用托管身份
from azure.storage.blob import BlobServiceClient
from azure.identity import DefaultAzureCredential

credential = DefaultAzureCredential()
blob_service_client = BlobServiceClient(
    account_url="https://myaccount.blob.core.windows.net",
    credential=credential
)

场景三:访问 Azure SQL Database

传统方式

# 使用 SQL 身份验证(用户名密码)
import pyodbc

server = "myserver.database.windows.net"
database = "mydb"
username = os.environ["DB_USERNAME"]
password = os.environ["DB_PASSWORD"]  # 密码存在哪里?

conn_str = f"DRIVER={{ODBC Driver 18 for SQL Server}};SERVER={server};DATABASE={database};UID={username};PWD={password}"
conn = pyodbc.connect(conn_str)

托管身份方式

# 使用 Azure AD 身份验证(托管身份)
import pyodbc
from azure.identity import DefaultAzureCredential

credential = DefaultAzureCredential()
token = credential.get_token("https://database.windows.net/.default")

server = "myserver.database.windows.net"
database = "mydb"

conn_str = f"DRIVER={{ODBC Driver 18 for SQL Server}};SERVER={server};DATABASE={database};Authentication=ActiveDirectoryMsi;Encrypt=yes"
conn = pyodbc.connect(conn_str, attrs_before={1256: bytearray(token.token, "UTF-8")})

2026 年如何使用托管身份

步骤一:启用托管身份

系统分配的托管身份

Azure Portal

  1. 进入资源(如 App Service)的页面
  2. 选择"身份"菜单
  3. 在"系统分配"标签下,将"状态"设置为"开"
  4. 点击"保存"

Azure CLI

# 为 App Service 启用系统分配的托管身份
az webapp identity assign --name myapp --resource-group myrg

# 为虚拟机启用系统分配的托管身份
az vm identity assign --name myvm --resource-group myrg

Azure PowerShell

# 为 App Service 启用系统分配的托管身份
Set-AzWebApp -Name myapp -ResourceGroupName myrg -AssignIdentity $true

用户分配的托管身份

Azure CLI

# 创建用户分配的托管身份
az identity create --name myidentity --resource-group myrg

# 获取身份的 client_id
az identity show --name myidentity --resource-group myrg --query clientId

# 将身份分配给 App Service
az webapp identity assign --name myapp --resource-group myrg --identities myidentity

步骤二:授予权限

启用托管身份后,需要为身份授予访问其他资源的权限。

使用 Azure RBAC

# 为托管身份授予 Storage Blob Data Reader 角色
az role assignment create \
  --assignee <managed-identity-principal-id> \
  --role "Storage Blob Data Reader" \
  --scope /subscriptions/<subscription-id>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<account>

# 为托管身份授予 Key Vault Secrets User 角色
az role assignment create \
  --assignee <managed-identity-principal-id> \
  --role "Key Vault Secrets User" \
  --scope /subscriptions/<subscription-id>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<vault>

使用 Key Vault 访问策略(旧方式):

az keyvault set-policy \
  --name myvault \
  --object-id <managed-identity-principal-id> \
  --secret-permissions get list

步骤三:在应用程序中使用

使用 Azure SDK

Azure SDK 的 DefaultAzureCredential 会自动尝试多种认证方式,包括托管身份:

from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient

# DefaultAzureCredential 会自动:
# 1. 尝试环境变量(ServicePrincipal)
# 2. 尝试托管身份(在 Azure 中运行时)
# 3. 尝试 Azure CLI(本地开发时)
# 4. 尝试 Visual Studio Code(本地开发时)
credential = DefaultAzureCredential()

blob_service_client = BlobServiceClient(
    account_url="https://myaccount.blob.core.windows.net",
    credential=credential
)

直接获取令牌

如果需要直接获取访问令牌:

import requests

# 通过 Azure Instance Metadata Service (IMDS) 获取令牌
# 仅在 Azure 中运行时可用
def get_access_token(resource):
    url = "http://169.254.169.254/metadata/identity/oauth2/token"
    params = {
        "api-version": "2018-02-01",
        "resource": resource
    }
    headers = {
        "Metadata": "true"
    }
    response = requests.get(url, params=params, headers=headers)
    return response.json()["access_token"]

# 获取 Storage 的访问令牌
token = get_access_token("https://storage.azure.com/")

步骤四:本地开发

在本地开发时,没有托管身份,可以使用以下方式:

  1. Azure CLI:登录 Azure CLI,DefaultAzureCredential 会自动使用 CLI 的凭据

    az login
    
  2. Azure PowerShell:登录 Azure PowerShell

    Connect-AzAccount
    
  3. Visual Studio Code:安装 Azure Account 扩展并登录

  4. 环境变量:使用 Service Principal 的环境变量(仅用于本地开发,不要提交到代码仓库)

最佳实践

1. 最小权限原则

  • 只为托管身份授予完成任务所需的最小权限
  • 使用 Azure RBAC 的细粒度角色,而非 Contributor 或 Owner
  • 定期审查权限分配,移除不再需要的权限

2. 使用用户分配的托管身份

在以下场景中,优先使用用户分配的托管身份:

  • 多个资源需要共享同一身份
  • 需要在创建资源之前预创建身份
  • 需要独立于资源生命周期管理身份
  • 需要在多个资源之间迁移身份

3. 避免混合使用凭据

  • 不要在使用托管身份的同时,又在配置文件中存储凭据
  • 全面迁移到托管身份,避免部分使用旧方式
  • 定期扫描代码和配置,确保没有硬编码的凭据

4. 监控和审计

  • 启用 Azure AD 审计日志,监控托管身份的操作
  • 使用 Azure Monitor 监控身份的使用情况
  • 设置异常行为告警(如异常时间、异常地点的访问)

5. 灾难恢复

  • 了解托管身份在区域故障时的行为
  • 对于关键应用,考虑使用用户分配的托管身份,以便在区域间迁移
  • 测试身份相关的故障场景

常见问题

Q: 托管身份可以跨租户使用吗?

A: 系统分配的托管身份只能在创建它的租户中使用。用户分配的托管身份也只能在创建它的租户中使用,但可以分配给该租户中的任何资源。

Q: 托管身份可以访问本地资源吗?

A: 托管身份是 Azure AD 身份,可以访问支持 Azure AD 认证的云资源。对于本地资源,需要通过 Azure AD Application Proxy 或其他方式集成。

Q: 托管身份的令牌有效期是多久?

A: 访问令牌的有效期通常为 1 小时。Azure SDK 会自动处理令牌的刷新,不需要手动管理。

Q: 可以在容器中使用托管身份吗?

A: 可以。在 Azure Kubernetes Service (AKS) 中,可以使用 Azure AD Workload Identity 为 Pod 分配托管身份。在 Azure Container Apps 中,也支持托管身份。

Q: 托管身份会产生费用吗?

A: 托管身份本身是免费的,不产生额外费用。

总结

Azure 托管身份提供了一种更安全、更易维护的方式来管理 Azure 资源的身份认证,彻底解决了"凭据存在哪里"的困境。

核心要点:

  1. 无需存储凭据:开发者不需要存储或管理任何密钥,消除了凭据泄露的风险
  2. 自动轮换:Azure 自动管理和轮换凭据,无需人工干预
  3. 细粒度控制:通过 Azure RBAC 精确控制身份的权限
  4. 统一管理:所有资源的身份管理方式一致,降低了管理复杂性
  5. 本地开发友好DefaultAzureCredential 在本地和 Azure 中都能正常工作

在 2026 年,托管身份已经成为 Azure 开发的最佳实践。对于新的 Azure 项目,应该从一开始就使用托管身份,而不是传统的存储凭据方式。对于现有项目,也应该逐步迁移到托管身份,提高安全性和可维护性。

正如文章所说,每个 Azure 项目最终都会面临"连接字符串存在哪里"的问题。而托管身份给出的答案是:哪里都不需要存

原文链接:https://dev.to/carlosjcastrog/why-azure-managed-identity-replaces-stored-credentials-and-how-to-use-it-in-2026-29cj

推荐文章

程序员茄子在线接单