使用 OIDC 保护 API 的应用服务 EasyAuth

App Services EasyAuth for protecting API with OIDC

我目前有一个解决方案,我有一个 OIDC 提供商、一个从该提供商获得令牌的客户端和一个受保护的资源 (API)。

目前我在 API 上使用 Easy Auth,到目前为止它似乎可以正确验证令牌。唯一的问题是 API 需要一个秘密(不是可选的)。

根据我的经验,API 应该能够检查签名、受众和到期时间等,而不需要 client_id 和 client_password 本身。在我看来,Easy Auth 假设一切都是客户端。

有没有一种方法可以使用 Easy Auth OIDC 来保护 API,其中 API 不需要密码,而只需验证知道 IDP 的令牌? (或者我需要使用其他 Azure 产品,例如 API 管理)

编辑:我想我刚刚了解到,在这种情况下,我可以向 secret 添加任何虚假值,但它不会被使用。客户端 ID 用作 Easy Auth 验证的受众。

听起来您正在遵循 API 中验证 JWT 的标准行为,而不是使用 OpenID Connect - 所以一切都很好。 OIDC 主要是客户关注的问题,这导致我有些困惑,因此我最初的回答。我想我会在下面添加一些后续要点,因为它们可能对您将来使用 Azure AD 时有用。

每个 API

的不同访问令牌

APIs 在 Azure AD 中注册 APIs 遵循 Resource Indicators 规范草案背后的基本原理。每个访问令牌只能由一个 API 使用。因此,每个 API 都需要注册一个客户端 ID,该 ID 被写入访问为 API 颁发的令牌。

OAUTH 标准和多个 APIs

当有多个 API 时,同一公司设置中最标准的 OAuth 2.0 架构是一组相关的 API 相互转发访问令牌。每个 API 然后验证访问令牌,这是一个快速操作。这是非常推荐的,有时称为 zero trust architecture。在微服务架构中,这还允许安全地维护用户上下文。

为此,一组相关的 API 应该能够全部声明相同的受众,例如 api.mycompany.com。同时每个API都会有不同的scope,保证如果调用了原client remit之外的API,请求会被立即拒绝。有关真实示例,请参阅 scope best practices

Azure AD 和多个 APIs

要让多个 API 使用 Azure AD 访问令牌相互调用,必须使用令牌交换。这涉及每个 API 充当客户端,在这种情况下,将使用您注册的客户端密码。 API 充当客户端的示例请求如下所示,来自我的 Node.js 示例。请注意,作为客户端的 API 将其原始令牌发送为 User Assertion:

const formData = new URLSearchParams();
formData.append('grant_type', 'urn:ietf:params:oauth:grant-type:jwt-bearer');
formData.append('client_id', this._configuration.graphClient.clientId);
formData.append('client_secret', this._configuration.graphClient.clientSecret);
formData.append('assertion', accessToken);
formData.append('scope', this._configuration.graphClient.scope);
formData.append('requested_token_use', 'on_behalf_of');

const options = {
    url: this._configuration.tokenEndpoint,
    method: 'POST',
    data: formData,
    headers: {
        'content-type': 'application/x-www-form-urlencoded',
        'accept': 'application/json',
    },
    httpsAgent: this._httpProxy.agent,
};

const response = await axios.request(options as AxiosRequestConfig) as any;
return response.data.access_token!;