MSAL 和 JWT,如何在客户端或服务器处理多个受众?

问题描述 投票:0回答:1

我正在努力与 2 个 .NET Core API 进行通信,这些 API 使用 Azure AD (Entra) 根据收到的请求对 JWT 承载进行身份验证。特别是,我尝试使用here中描述的方法使用客户端密钥和 TenantId 从我们的 Entra 服务器获取 JWT 令牌。我可以毫无问题地得到这个,但是当我尝试使用它与我的其他应用程序通信时,我收到 401 未经授权的响应。这是一个快速、可怕的草图: enter image description here

第二个API的配置如下:

services.AddAuthentication(options =>
 {
     options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
     options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
 }).AddJwtBearer(options =>
 {
     options.Authority = configuration.GetValue<string>("Authentication:Authority");
 });

services.AddOptions<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme)
    .Configure<IConfiguration>((options, configuration) =>
    {
        configuration.GetSection("Authentication").Bind(options);
    });

services.AddAuthorization();

有了这个,理论上我就设置了权威和受众。当使用我们在使用 MS 登录登录时获得的令牌从前端(第三个应用程序)进行通信时,效果很好,但是使用我使用 ConfidentialClientApplication 实例获得的令牌时,我得到了 401。这是我创建的用于处理令牌的类获取:

public class ConfidentialClient : IConfidentialClient
{
    private readonly AzureADOptions _ADOConfig;
    
    // This object will cache tokens in-memory - keep it as a singleton
    private readonly IConfidentialClientApplication clientApp;

    public ConfidentialClient(IOptions<AzureADOptions> options) 
    {
        this._ADOConfig = options.Value;
        this.clientApp = ConfidentialClientApplicationBuilder.Create(_ADOConfig.ClientId)
            .WithClientSecret(_ADOConfig.ClientCredentials.First().ClientSecret)
            .Build();
    }

    public async Task<string> GetToken()
    {
        // When making the request, specify the tenant-based authority
        var authResult = await this.clientApp.AcquireTokenForClient(scopes: new[] { _ADOConfig.Scopes.First() })
                .WithTenantId(_ADOConfig.TenantId)
                .ExecuteAsync();

        return authResult.AccessToken;
    }
}

我可以获得令牌,但 API 拒绝了它。在比较这 2 个令牌时,我可以看到的主要区别之一是受众,我从 ConfidentialClient 获得的令牌上设置的令牌看起来很通用,并且与接收应用程序的 JWT 身份验证策略上配置的令牌不同(以及由前端),我认为令牌因此被拒绝。

有没有办法为 ConfidentialClient 配置特定受众,或者以可以接受多个受众的方式配置 JWTBearer 身份验证策略?

authentication jwt asp.net-core-webapi azure-ad-msal azure-entra-id
1个回答
0
投票

我不太明白您想要实现的目标,但根据您的架构图,您似乎有一个允许用户登录的前端客户端应用程序,并且它将为您生成用于调用后端的访问令牌服务器API。同时,您有 2 个受 Azure AD 保护的 API。这是一种常见的场景,但是您正在尝试使用客户端凭据流(根据您在问题中共享的链接)来生成专为守护程序应用程序而不是您的场景设计的访问令牌。

根据我的理解,您可能有 2 或 3 个 Azure AD 应用程序,其中一个用于用于身份验证的前端应用程序,1 或 2 个用于公开 API 的应用程序,并用作

scope
参数来生成访问令牌以调用 2 个 API。您可以查看此文档为您的API项目启用AAD保护,这与您分享的代码片段略有不同。

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));

这是您应该在 Program.cs 中看到的内容。您可以使用VS模板创建一个新的API项目,但请选择

Microsoft Identity Platform
作为身份验证类型,您将直接拥有所有必需的配置和代码,以便您可以看到需要的内容。

© www.soinside.com 2019 - 2024. All rights reserved.