ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

BuildKit 项目中的 Go Azure Identity 认证指南:azidentity 凭据体系与 DefaultAzureCredential 实战

2026/9/15 13:02:22 拓冰建站 浏览量
BuildKit 项目中的 Go Azure Identity 认证指南:azidentity 凭据体系与 DefaultAzureCredential 实战 BuildKit 项目中的 Go Azure Identity 认证指南azidentity 凭据体系与 DefaultAzureCredential 实战【免费下载链接】buildkitconcurrent, cache-efficient, and Dockerfile-agnostic builder toolkit项目地址: https://gitcode.com/GitHub_Trending/bu/buildkit本文基于本仓库 vendor 目录中 azidentity README 整理而成。azidentity是 Azure SDK for Go 的认证核心模块为整个 Azure SDK 提供基于 Microsoft Entra ID原 Azure Active Directory的令牌认证能力。在本仓库中它被 azblob 远程缓存 直接使用当使用 Azure Blob Storage 作为 BuildKit 的远程缓存后端且未配置共享密钥时即通过azidentity.NewDefaultAzureCredential(nil)完成认证。读完本文你将掌握 azidentity 的安装方式、全部凭据类型、DefaultAzureCredential 的认证链顺序与筛选机制、ChainedTokenCredential 的自定义组合方式以及环境变量、令牌缓存、日志排障等完整实操能力并能理解 BuildKit 中 azblob 缓存后端的认证细节。一、模块定位与核心概念azidentity是 Azure SDK for Go 中提供 Microsoft Entra ID 令牌认证支持的模块。它实现了一组TokenCredential类型这些凭据可以被任何支持令牌认证的 Azure SDK 客户端直接使用。凭据Credential是 azidentity 的核心抽象它是一个包含、或能够获取服务客户端认证请求所需数据的类型。Azure SDK 中的所有服务客户端在构造时都会接收一个凭据实例并使用该凭据对每次请求进行认证。azidentity专注于与 Microsoft Entra ID 的 OAuth 认证提供多种能够获取 Microsoft Entra 访问令牌的凭据类型。从本仓库 vendor 的源码看azidentity的凭据实现位于 vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/其中核心的TokenCredential接口要求实现GetToken(ctx, policy.TokenRequestOptions)方法该方法返回访问令牌或错误见 azidentity.go。二、安装与前置条件本模块遵循 Go Modules 版本管理规范通过标准 Go 命令安装go get -u github.com/Azure/azure-sdk-for-go/sdk/azidentity前置条件一个 Azure 订阅用于实际调用 Azure 服务受支持版本的 Go模块源码使用go1.18构建标签见各凭据文件顶部的//go:build go1.18约束。三、本地开发环境的认证方式在本地调试和执行代码时开发者通常使用自己的账号来认证 Azure 服务调用。azidentity支持通过开发者工具完成认证以简化本地开发流程。3.1 通过 Azure CLI 认证DefaultAzureCredential和AzureCLICredential可以以登录 Azure CLI 的用户身份进行认证# 登录 Azure CLI在带有默认浏览器的系统上会拉起浏览器完成认证 az login # 无默认浏览器时使用设备码device code流程也可手动指定 az login --use-device-code3.2 通过 Azure Developer CLI 认证在 IDE 之外编码的开发者可以使用 Azure Developer CLIazd。使用DefaultAzureCredential或AzureDeveloperCLICredential的应用在本地运行时可以使用登录到azd的账号进行认证# 默认浏览器认证 azd auth login # 无默认浏览器时使用设备码流程 azd auth login --use-device-code四、DefaultAzureCredential开箱即用的认证链DefaultAzureCredential旨在简化最终部署到 Azure 的应用的认证体验它将 Azure 托管环境使用的凭据与本地开发使用的凭据组合在一起开发者几乎无需关心环境差异即可完成认证。4.1 认证链顺序从 default_azure_credential.go 的源码实现可以看出DefaultAzureCredential本质上是内部构建的一个ChainedTokenCredential按以下顺序依次尝试各凭据直到某个凭据成功返回令牌为止EnvironmentCredential——读取环境变量配置的凭据WorkloadIdentityCredential——当 Azure 工作负载身份 webhook 设置了环境变量配置时启用若需更多控制建议直接使用WorkloadIdentityCredentialManagedIdentityCredential——Azure 资源的托管身份AzureCLICredential——Azure CLI 登录用户AzureDeveloperCLICredential——Azure Developer CLI 登录用户AzurePowerShellCredential——Azure PowerShell 登录用户。其中第 3 步ManagedIdentityCredential在DefaultAzureCredential链中会启用特殊的 IMDS实例元数据服务探测行为仅当链中还有其他凭据时才启用对应源码中的dac: selected^managedIdentity ! 0逻辑避免在非 Azure 环境里长时间等待 IMDS 超时。一旦链中某个凭据认证成功DefaultAzureCredential在后续的每次认证中都会复用该凭据不再重试失败过的来源。4.2 用 AZURE_TOKEN_CREDENTIALS 筛选认证链源码还提供了对认证链的精细化控制设置环境变量AZURE_TOKEN_CREDENTIALS可以只尝试链中的部分凭据其合法值包括| 值 | 效果 | | - | - | |dev| 依次尝试AzureCLICredential、AzureDeveloperCLICredential、AzurePowerShellCredential| |prod| 依次尝试EnvironmentCredential、WorkloadIdentityCredential、ManagedIdentityCredential| | 任一凭据类型名 | 仅尝试该类型例如EnvironmentCredential、AzureCLICredential|如果希望强制要求必须设置AZURE_TOKEN_CREDENTIALS可以在构造时设置DefaultAzureCredentialOptions.RequireAzureTokenCredentials此时若变量未设置NewDefaultAzureCredential会直接返回错误。4.3 其他可配置选项DefaultAzureCredentialOptions还支持AdditionallyAllowedTenants额外允许认证的租户列表也可通过环境变量AZURE_ADDITIONALLY_ALLOWED_TENANTS以分号分隔设置通配符*表示允许任意租户DisableInstanceDiscovery仅适用于离线云或私有云如 Azure Stack场景设为true可跳过向https://login.microsoft.com请求 Entra 实例元数据TenantID为 Azure CLI、Azure Developer CLI 及工作负载身份认证设置默认租户。4.4 代码示例使用DefaultAzureCredential认证armresources模块的客户端cred, err : azidentity.NewDefaultAzureCredential(nil) if err ! nil { // handle error } client : armresources.NewResourceGroupsClient(subscription ID, cred, nil)4.5 为 DefaultAzureCredential 指定用户分配的托管身份要配置DefaultAzureCredential认证一个用户分配的托管身份只需将环境变量AZURE_CLIENT_ID设置为该身份的客户端 ID。在 default_azure_credential.go 中可以看到构造ManagedIdentityCredential时正是通过os.LookupEnv(azureClientID)读取该变量并将其作为o.ID ClientID(ID)传入的。五、Managed Identity托管身份支持DefaultAzureCredential和ManagedIdentityCredential支持在任意支持托管身份的宿主环境中进行托管身份认证典型环境包括列表非穷尽Azure App ServiceAzure ArcAzure Cloud ShellAzure Kubernetes ServiceAzure Service FabricAzure Virtual Machines六、ChainedTokenCredential自定义认证流程DefaultAzureCredential通常是上手最快的选择对于更高级的场景ChainedTokenCredential将多个凭据实例链接起来按顺序尝试。它会逐个调用链中每个凭据直到某一个返回令牌若某个凭据因错误而无法认证则继续尝试下一个源码中仅当错误类型为credentialUnavailableError时才继续向下一个来源尝试见 chained_token_credential.go。默认行为下一旦某个凭据成功之后的每次认证都直接复用该成功凭据ChainedTokenCredentialOptions.RetrySources默认false若希望每次都重新依次尝试所有来源可将RetrySources设为true。示例优先使用托管身份不可用时回退到 Azure CLImanaged, err : azidentity.NewManagedIdentityCredential(nil) if err ! nil { // handle error } azCLI, err : azidentity.NewAzureCLICredential(nil) if err ! nil { // handle error } chain, err : azidentity.NewChainedTokenCredential([]azcore.TokenCredential{managed, azCLI}, nil) if err ! nil { // handle error } client : armresources.NewResourceGroupsClient(subscription ID, chain, nil)从源码看NewChainedTokenCredential会对传入的凭据做严格校验至少包含一个非 nil 的TokenCredential否则直接返回错误。七、凭据类型速查表7.1 凭据链| 凭据 | 用途 | | - | - | |DefaultAzureCredential| 简化 Azure 应用开发的上手认证体验组合本地与托管环境凭据 | |ChainedTokenCredential| 组合多个凭据定义自定义认证流程 |7.2 Azure 托管应用认证| 凭据 | 用途 | | - | - | |EnvironmentCredential| 通过环境变量配置的服务主体或用户认证 | |ManagedIdentityCredential| 认证 Azure 资源的托管身份 | |WorkloadIdentityCredential| 在 Kubernetes 上认证工作负载身份 |7.3 服务主体认证| 凭据 | 用途 | | - | - | |AzurePipelinesCredential| 认证 Azure Pipelines 服务连接 | |ClientAssertionCredential| 使用签名客户端断言认证服务主体 | |ClientCertificateCredential| 使用证书认证服务主体 | |ClientSecretCredential| 使用机密secret认证服务主体 |7.4 用户认证| 凭据 | 用途 | | - | - | |InteractiveBrowserCredential| 使用默认网页浏览器进行交互式用户认证 | |DeviceCodeCredential| 在 UI 受限的设备上进行交互式用户认证 |7.5 开发工具认证| 凭据 | 用途 | | - | - | |AzureCLICredential| 以登录 Azure CLI 的用户身份认证 | |AzureDeveloperCLICredential| 以登录 Azure Developer CLI 的用户身份认证 | |AzurePowerShellCredential| 以登录 Azure PowerShell 的用户身份认证 |八、环境变量配置详解DefaultAzureCredential和EnvironmentCredential均可通过环境变量配置。每种认证方式需要特定变量的取值。8.1 服务主体 机密secret| 变量名 | 取值 | | - | - | |AZURE_CLIENT_ID| Microsoft Entra 应用的 ID | |AZURE_TENANT_ID| 应用所属 Microsoft Entra 租户的 ID | |AZURE_CLIENT_SECRET| 应用的某个客户端机密 |8.2 服务主体 证书| 变量名 | 取值 | | - | - | |AZURE_CLIENT_ID| Microsoft Entra 应用的 ID | |AZURE_TENANT_ID| 应用所属 Microsoft Entra 租户的 ID | |AZURE_CLIENT_CERTIFICATE_PATH| 包含私钥的证书文件路径 | |AZURE_CLIENT_CERTIFICATE_PASSWORD| 证书文件密码如有 |配置按上述顺序尝试例如当客户端机密与证书的值同时存在时优先使用客户端机密。从 environment_credential.go 的源码实现看EnvironmentCredential实际还支持第三种形式——用户名密码认证AZURE_USERNAMEAZURE_PASSWORD其内部按机密 → 证书 → 用户名密码的优先级委派给对应的ClientSecretCredential、ClientCertificateCredential或UsernamePasswordCredential。证书场景下若模块内置的ParseCertificates无法解析你的证书源码会提示改用ClientCertificateCredential此外AZURE_CLIENT_SEND_CERTIFICATE_CHAIN可控制是否发送完整证书链取值为1或true时启用。除上述变量外azidentity 源码azidentity.go还定义了以下常用环境变量AZURE_AUTHORITY_HOST覆盖默认的 Entra 权威主机默认 Azure 公有云要求必须为https协议AZURE_ADDITIONALLY_ALLOWED_TENANTS分号分隔的额外允许租户列表AZURE_FEDERATED_TOKEN_FILE工作负载身份使用的联合令牌文件路径。九、令牌缓存Token Caching令牌缓存是azidentity的特性它允许应用默认在内存中缓存令牌或选择性地在磁盘上持久化缓存提升弹性和性能减少向 Microsoft Entra ID 发起获取访问令牌的请求次数。本仓库 vendor 目录下 TOKEN_CACHING.MD 对缓存机制做了更细致的说明缓存不可关闭只要凭据带有缓存它只会在缓存无法提供令牌时才请求新令牌。Azure SDK 服务客户端还有一层独立的内存令牌缓存任何凭据包括自定义实现都无法关闭。内存缓存默认支持缓存的凭据类型默认在内存中缓存令牌无需任何配置每个凭据实例拥有独立缓存两个实例之间不共享。持久化缓存可选部分凭据类型支持跨进程持久化缓存避免应用每次运行都重新认证。持久化缓存按操作系统加密存储Linux 使用内核密钥保留服务keyctl系统关机后缓存数据会丢失、macOS 使用钥匙串Keychain需 cgo 与图形会话headless 环境不可用、Windows 使用 DPAPI。各凭据缓存支持情况节选关键项ClientSecretCredential、ClientCertificateCredential、ClientAssertionCredential、InteractiveBrowserCredential、DeviceCodeCredential等同时支持内存与持久化缓存DefaultAzureCredential仅当链中目标凭据支持时才生效且不支持持久化EnvironmentCredential、ManagedIdentityCredential、OnBehalfOfCredential仅支持内存缓存AzureCLICredential、AzureDeveloperCLICredential、AzurePowerShellCredential两种缓存均不支持。十、故障排查10.1 错误处理凭据在认证失败或缺少认证所需数据时返回error。ChainedTokenCredential的源码将错误统一整理为两类所有来源都返回凭据不可用时返回credentialUnavailableError否则返回AuthenticationFailedError并附带每个已尝试凭据的详细错误信息见 chained_token_credential.go 中的createChainedErrorMessage。此外default_azure_credential.go中有一个defaultCredentialErrorReporter当链中某个凭据因配置缺失而无法构造时它会作为占位凭据加入链中确保该构造错误信息最终出现在GetToken返回的错误里方便定位。10.2 日志本模块使用azcore中基于分类的日志实现。要为所有 SDK 模块开启控制台日志设置环境变量AZURE_SDK_GO_LOGGINGall也可以使用azcore/log包控制日志输出或仅为azidentity开启日志。例如import azlog github.com/Azure/azure-sdk-for-go/sdk/azcore/log // print log output to stdout azlog.SetListener(func(event azlog.Event, s string) { fmt.Println(s) }) // include only azidentity credential logs azlog.SetEvents(azidentity.EventAuthentication)凭据只记录基本信息如GetToken成功/失败及错误。这些日志条目不包含认证机密但可能包含敏感信息生产环境需注意日志脱敏。十一、在 BuildKit 中的实战应用azblob 远程缓存认证本仓库将azidentity用于 Azure Blob Storage 远程缓存后端的认证。在 cache/remotecache/azblob/utils.go 的createContainerClient函数中可以看到两条认证路径共享密钥路径当缓存配置了secret_access_key属性时使用azblob.NewSharedKeyCredentialazblob.NewClientWithSharedKeyCredential完成认证azidentity 路径默认未配置共享密钥时调用azidentity.NewDefaultAzureCredential(nil)创建默认凭据再通过azblob.NewClient(config.AccountURL, cred, azblob.ClientOptions{})创建 Blob 客户端。这意味着在 Azure 虚拟机、AKS、App Service 等托管环境中BuildKit 会自动借助环境变量、托管身份、工作负载身份或 Azure CLI 登录凭据完成认证无需显式配置密钥。azblob 缓存后端的配置来源同样遵循属性优先、环境变量兜底的规则相关环境变量包括| 环境变量 | 含义 | 默认值 | | - | - | - | |BUILDKIT_AZURE_STORAGE_ACCOUNT_URL| 存储账户 URL必填或通过account_url属性指定 | 无 | |BUILDKIT_AZURE_STORAGE_ACCOUNT_NAME| 存储账户名 | 从账户 URL 主机名推断 | |BUILDKIT_AZURE_STORAGE_CONTAINER| 缓存容器名 |buildkit-cache| |BUILDKIT_AZURE_STORAGE_PREFIX| 缓存键前缀 | 空 |容器不存在时createContainerClient会自动创建首次调用GetProperties返回ContainerNotFound后调用Create。配合 exporter.go 中的导出逻辑UploadStream分块上传、IfNoneMatch条件避免重复上传内容寻址的 blobBuildKit 可以在 Azure Blob Storage 上实现高效、并发的远程缓存共享。十二、下一步与延伸阅读Azure SDK 各客户端与管理模块如armresources、azblob等都支持使用azidentity的凭据类型进行认证。如需在本仓库中继续深入可以重点阅读凭据链实现default_azure_credential.go 与 chained_token_credential.go环境变量凭据environment_credential.go缓存机制TOKEN_CACHING.MDBuildKit 集成cache/remotecache/azblob/utils.go 与 cache/remotecache/azblob/exporter.go。实践建议生产环境优先使用具体的凭据类型如ManagedIdentityCredential、WorkloadIdentityCredential而非DefaultAzureCredential这样认证行为更可预测、更易排查——这也是 azidentity 官方文档与源码注释中反复强调的最佳实践。【免费下载链接】buildkitconcurrent, cache-efficient, and Dockerfile-agnostic builder toolkit项目地址: https://gitcode.com/GitHub_Trending/bu/buildkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考