我正在努力与 2 个 .NET Core API 进行通信,这些 API 使用 Azure AD (Entra) 根据收到的请求对 JWT 承载进行身份验证。特别是,我尝试使用here中描述的方法使用客户端密钥和 TenantId 从我们的 Entra 服务器获取 JWT 令牌。我可以毫无问题地得到这个,但是当我尝试使用它与我的其他应用程序通信时,我收到 401 未经授权的响应。这是一个快速、可怕的草图:
第二个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 身份验证策略?
我不太明白您想要实现的目标,但根据您的架构图,您似乎有一个允许用户登录的前端客户端应用程序,并且它将为您生成用于调用后端的访问令牌服务器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
作为身份验证类型,您将直接拥有所有必需的配置和代码,以便您可以看到需要的内容。