azure - 如何从本地运行的非交互式进程获取 Azure 访问目录访问令牌,而不共享机密?
问题描述
在 Azure Active Directory 上对非交互式进程进行身份验证的标准模式是:
- 当服务在 Azure 上运行时,使用托管标识。
- 只要托管身份不可用,请使用OAuth 2.0 客户端凭据流。
但是,#1 不适用于在本地运行的服务,而#2 需要共享机密,这增加了很多操作复杂性——密钥存储、保护和轮换。
问题:
对于 Azure Active Directory 与 Active Directory 联合的设置(参见图表),是否有办法让本地运行的非交互式服务在不共享任何机密的情况下从 Azure Active Directory 获取访问令牌?所有必需的信任关系似乎都已到位,但有没有办法完成它?
解决方案
简短的回答是肯定的。
成分
- 与 Active Directory 联合的 Azure Active Directory 租户,能够使用 Windows 身份验证进行单点登录。
- 授予 user_impersonation 权限的应用程序注册。
- 您的 MSAL 请求的特定配置。
细节
为了实现这一点,您需要使用 OAuth 2.0 代表流程,为此,您需要在 AAD 上创建应用程序注册。确保为您希望本地应用程序能够访问的每个 API 的“user_impersonation”范围“授予管理员同意”。典型的例子是:
- Azure Key Vault.user_impersonation
- Azure SQL 数据库.user_impersonation
- Azure Storage.user_impersonation
- Microsoft Graph.user_impersonation
但实际上,没有限制。此外,请注意安全影响很小,因为您没有授予任何权限。您只是允许任何能够针对此应用程序注册进行身份验证的用户继续并尝试在他们自己的权限下访问授予的资源。
应用程序注册准备就绪后,您需要使用以下代码获取令牌:
const string ApplicationRegistrationId = "the id";
const string Tenant = "YourDomain.com";
// Any user name will do as long as it's in your domain. This is because AAD will redirect the request to the federated Identity Provider, which will then use Kerberos, which will the real user.
const fakeUsername = "anything@YourDomain.com";
// The user_impersonation scopes you want to access. They need to have been granted on the Application Registration. The example below is for Azure Storage:
var scopes = new string[] { "https://storage.azure.com/user_impersonation" };
var app = PublicClientApplicationBuilder.Create(ApplicationRegistrationId).WithAuthority(Tenant).Build();
var authenticationResult = await app.AcquireTokenByIntegratedWindowsAuth(scopes).WithUsername(fakeUsername).ExecuteAsync();
// Go ahead and use the AccessToken from authenticationResult.AccessToken
图表
笔记
我没有发现上述方法记录在其他任何地方,但它被证明是有效的,并且鉴于它消除了共享任何秘密的需要 - 没有管理、轮换等 - 很高兴看到它被 Microsoft 记录下来。
它在具有混合设置的企业环境中特别适用和有用,即在本地运行的服务和部署到 Azure 的资源。
推荐阅读
- r - ggplot 在单独的代码中工作,但不能在循环中工作
- postgresql - 在 postgres 上查询统计信息
- r - 如何修复轮盘赌游戏(函数、循环和条件语句)
- flutter - VSCode 中的 Flutter 未连接到 devtools
- java - 了解 Spring Boot 中的 @ModelAttribute 和 @RequestMapping
- python - 使用 pm4py 从事件日志中获取图表
- c# - 在 Image Target 渲染之前,具有重力的物体会持续下落
- xcode - 使用 Xcode 进行 Windows 编程
- c++ - c(0) 是 c = 0 的缩写吗?
- typescript - TypeScript 可变参数元组类型推断问题,用于运行一系列“结果”返回函数的函数