用于多个 WebApi 端点的 Azure AD 不记名令牌?

Posted

技术标签:

【中文标题】用于多个 WebApi 端点的 Azure AD 不记名令牌?【英文标题】:Azure AD Bearer Token For Multiple WebApi Endpoints? 【发布时间】:2018-09-21 14:16:44 【问题描述】:

我们正在使用 Angular、.Net WebApi 和 Azure 构建多个应用程序。我们一直在做的是通过隐式 oAuth2/OIDC 授权流通过 Azure AD 保护应用程序。

一切运行良好,但到目前为止我们的架构很简单。 IE '前端 App1' -> 'WebApi App1'

当我们向 AAD 请求令牌时,我们会在令牌请求中发送资源(“WebApi App1”的应用程序 ID)。这似乎是令牌请求中的必需属性。这是如何扩展的?

假设我们遇到“前端 App1”需要与“WebApi App1”和“WebApi App2”通信的情况。我们是否需要发出多个令牌请求?人们在 Azure 中的这些情况下会做什么?将不记名令牌紧密耦合到一个资源似乎很不稳定。

似乎另一种方法是我可以将两个 api 应用程序配置为验证同一 Azure 租户和应用程序 ID 的令牌。这样,令牌对任何一个应用程序都有好处,但这也不是很灵活,因为这意味着任何一个应用程序的所有令牌都对另一个应用程序有好处......

【问题讨论】:

我也有类似的情况。只有我们正在考虑使用 API 管理服务来处理这个问题。 【参考方案1】:

你有两个选择:

    获得两个令牌 对两个 API 使用相同的应用 ID

为每个 API 获取一个令牌是正常的方法。

Azure AD 中的不记名令牌始终仅对一个 API 有效。 它可以包含该 API 上调用用户/应用程序的范围/角色,这些值是应用程序清单中定义的简单字符串,例如用户阅读。 这些值可以在 API 之间重叠,因此我们不能拥有对两个 API 有效的令牌。

【讨论】:

如果您在两个 API 中定义了相同的范围,客户端应用程序不能仅将权限委派给其中一个 API 中的一个范围,而不是另一个?似乎 AAD 中的权限屏幕支持这种粒度级别... 是的,这正是我的观点。如果您有 API 1 和 API 2,并且都定义了一个范围“Things.Read”。客户端应用程序有权调用具有 Things.Read 范围的 API 1,但不能调用 API 2。然后,如果可以获取适用于两个 API 的令牌,则客户端可以调用 API 2,即使它没有权限这样做。 在您概述的情况下,如果客户端使用 Things.Read 配置到 API1,但客户端尚未在 AAD 权限授予屏幕中被委派 API2 Things.Read,那么 API2 不会知道它不允许请求? 没有。 API 不会每次都询问 Azure AD 调用是否有效。它依赖于检查令牌的签名,在这种情况下应该是有效的。我忘记提及的另一个字段是 audience,它位于令牌中,用于标识令牌的目标。因此,根据定义,令牌是针对特定 API 的。 感谢您的澄清,但我对这种行为有点失望。从同一个应用程序获取多个令牌对最终用户来说是一个很大的不便,因为我们会将它们从应用程序重定向到验证并返回应用程序几次......并且在后端使用相同的 appId 确实会横向扩展也可以。【参考方案2】:

问题说明:如何使用 UI 应用程序中的相同令牌调用多个 WebApi。

我的解决方案:

假设有两个Web-Api,WebApi01 和WebApi02。 在 Azure AD 中,我没有注册两个应用程序,而是只注册了一个应用程序,比如 MasterAPI。 此外,客户端应用程序,即 UI 应用程序必须像往常一样注册。

MasterAPI 不是一个实际的应用程序。因此,可能没有任何重定向 URL,我们也不需要任何重定向 URL。在此 API 中,我们首先为每个 WebAPI(WebAPI01 和 WebAPI02)声明两个范围。我通常遵循 App.Feature.Verb 等命名法。因此,范围名称将类似于 Master.WebAPI01.ReadMaster.WebAPI02.Read。 p>

它们将像 api://MasterAPI-Application-Id//Master.WebAPI01.Readapi://MasterAPI-Application-Id//Master.WebAPI02 一样公开。在 azure 应用程序注册页面中阅读

在访问令牌请求期间,我将这两个范围传递给 Azure AD 端点。我得到的响应包含范围声明 (scp),其值为“Master.WebAPI01.Read Master.WebAPI02.Read”。

"scp":"Master.WebAPI01.Read Master.WebAPI02.Read"

通过这种方式,我告诉系统受信任的 Client-UI 应用程序具有可访问两个功能的令牌。 简而言之,任何可以登录客户端应用程序的人都可以访问这两个功能。 现在,经过身份验证的用户有权使用两项功能。

这可以进一步限制。说,我,管理员,应该控制谁可以访问什么。 为此,我必须实现基于角色的访问控制 (RBAC)。我在 MasterAPI 中定义了自定义应用程序角色。 这可以通过操纵清单来完成。

现在,当我收到访问令牌时,我会获得带有值集的角色声明。该值取决于分配给用户的角色。

“角色”:[ "Access_WebAPI01", “Access_WebAPI02” ],

token 通过 header 传递给资源 WebAPI(在本例中为 WebAPI01 或 WebAPI02)。接收者 WebAPI 然后解析 header token 以检查是否存在所需的角色。

因此,简而言之,Scope 和 RBAC 组合对我有用。而且我不必为身份验证和授权访问数据库。

如果添加了新功能,例如 WebAPI03。我需要做的就是在 MasterAPI 中设置范围。并且使用现有角色或为用户分配新角色。

PS:为什么选择 MasterAPI?在 Azure AD 中,所有范围只能来自一个资源。

【讨论】:

以上是关于用于多个 WebApi 端点的 Azure AD 不记名令牌?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 .NET Core 2.2 WebApi 和 Azure AD 2.0 中配置 Swagger?

为 Web API 实施 Azure AD 身份验证,可以在有和没有用户上下文的情况下从多个客户端调用?

从 URL Azure AD 捕获访问令牌以用于令牌

在 Azure AD B2C 中请求令牌时缺少范围“scp”

带有 JWT Bearer 令牌和 ASP.NET Core 2 WebApi 的 Azure AD 用户信息

APIUrl 前缀不适用于 Azure APIM