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

Posted

技术标签:

【中文标题】为 Web API 实施 Azure AD 身份验证,可以在有和没有用户上下文的情况下从多个客户端调用?【英文标题】:Implement Azure AD authentication for Web API which can be called from multiple clients with and without user context? 【发布时间】:2021-10-26 07:32:36 【问题描述】:

Net 核心应用程序和单页应用程序。我已经实现了用于身份验证的授权代码流。在 SPA 中,用户登录并调用 API。这按预期工作。所以我的 WebAPI 接受来自 SPA 的请求,并且只有经过身份验证的请求(例如令牌)包含角色。现在我有这样的要求,即我应该向同一个应用程序添加一个控制器,该应用程序可以接受来自另一个客户端应用程序的请求。此客户端应用程序没有登录用户。因此,它是一种服务到服务调用的服务,例如客户端凭据流。现在我想实现第二个流程。因此,最终我的 Web API 可以通过经过身份验证的用户从 SPA 调用,也可以从没有经过身份验证的用户的另一个应用程序调用。我正在尝试实现这一点,但不确定这种方式是否可行。原因是我在 web api 中有以下代码

var policy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
        services.AddMvc(options =>
        
            options.Filters.Add(typeof(ValidateModelStateAttribute));
            options.Filters.Add(new AuthorizeFilter(policy));
        )
        .SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
        .AddNewtonsoftJson(options => 
            options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
        );

这表示在应用中只允许经过身份验证的用户。我为我的另一个客户端应用程序生成了令牌,如下所示

https://login.microsoftonline.com/tenantid/oauth2/v2.0/token

并将客户端 ID、客户端密钥 grant_type 和范围作为 webapi 的 api://clientid 传递。我得到了令牌并尝试访问 Web API,但这无法成功。它抛出错误

System.UnauthorizedAccessException:IDW10201:既不是作用域也不是角色 在不记名令牌中找到声明。

我需要一些帮助,首先这是可能的,然后如果可能的话,什么是正确的方法或我在这里遗漏的任何东西。有人可以帮帮我吗。任何帮助,将不胜感激。谢谢

【问题讨论】:

【参考方案1】:

您需要在 Azure AD 管理门户中转到您的应用注册,找到“应用角色”,并使用允许的成员类型“应用程序”创建应用角色。 这是一个应用程序权限。

然后您需要为客户端应用程序进行应用程序注册,并在 API 权限下添加该应用程序权限。 然后,您需要征得管理员同意才能将权限授予客户端应用程序。

对于不涉及用户的系统之间的集成,您应该始终定义应用程序权限。 您可以拥有任意多或尽可能少的粒度,您可以拥有一个允许访问所有端点的应用程序权限,或者您可以拥有您公开的每个实体类型的权限(类似于 MS Graph API)。

【讨论】:

感谢 Junnas 的回答。在没有用户参与的情况下生成令牌时,我应该使用上面提到的客户端凭据流权。所以我应该传递 webapi 的客户端 ID 和客户端密码,我可以知道我应该传递的范围吗? 嗨 Junnas,我指的是 joonasw.net/view/defining-permissions-and-roles-in-aad。你在那里解释得很好。我们可以将类型设置为应用程序,我们可以生成令牌。我唯一的困惑是我的 API 会接受来自两者的令牌(当我说两者都登录用户令牌时,还有一个是具有角色但没有用户信息的客户端应用程序令牌)。你能确认一下吗 如果您使用 Microsoft.Identity.Web (并且我认为您是基于错误消息),那么是的,它将支持这两种情况。没错,您使用客户端凭据流将令牌作为应用程序获取,而无需用户参与。 在上述过程中,令牌中的“aud”受众将是应用程序 ID。如果是用户令牌和客户端凭据令牌,则从不同的应用程序生成。如果您在令牌验证中启用受众检查,那么您将必须维护预期的受众 ID。 这对我有用。我的 API 能够使用 lgged inuser 从 ui 访问,也可以在没有用户在场的情况下从其他客户端应用程序访问。非常感谢君纳斯。两者都有效

以上是关于为 Web API 实施 Azure AD 身份验证,可以在有和没有用户上下文的情况下从多个客户端调用?的主要内容,如果未能解决你的问题,请参考以下文章

Azure AD 身份验证 401 错误“受众无效” AddAzureADBearer .Net Core Web Api

使用 azure AD B2C 进行 blazor web api 身份验证

Azure AD B2C 与 ASP.NET Web API 发出令牌,用于 Web API 中的身份验证和访问 MS Graph API

使用用户模拟来调用Azure AD Microsoft API的Web API

使用 Azure Ad Auth 从 .NET Core Web API 读取/写入 Azure Blob

Azure AD 在 Web API 中使用来自客户端应用程序的令牌