c# - Microsoft Graph API 授权错误:无效的受众
问题描述
我知道这是一个很长的问题,但如果有人能与我分享他们的想法或经验,我将不胜感激,因为我已经在这方面工作了几天,现在正在尝试很多事情。我有一个 ASP Net Core 3.1 Web API 应用程序和一个 ASP.NET Core 3.1 MVC 应用程序。
两者都已在 Azure AD 中注册。API 项目应该根据从 MVC 项目接收到的请求负载创建日历事件。我正在按照此处链接中的 Microsoft 说明进行操作
但是,一旦 API 项目对 Microsoft Graph 进行调用,它就会失败并出现以下错误:
"code": "InvalidAuthenticationToken",
"message": "访问令牌验证失败。无效的受众。",
我在这里提供了更多信息,但可以从上面的链接下载整个示例。
ASP.NET 核心 MVC Startup.cs
:
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddAzureAd(options =>
{
Configuration.Bind("AzureAd", options);
AzureAdOptions.Settings = options;
})
.AddCookie();
ASP.NET Core MVC 项目AddAzureAd
功能:
public static AuthenticationBuilder AddAzureAd(this AuthenticationBuilder builder, Action<AzureAdOptions> configureOptions)
{
builder.Services.Configure(configureOptions);
builder.Services.AddSingleton<IConfigureOptions<OpenIdConnectOptions>, ConfigureAzureOptions>();
builder.AddOpenIdConnect();
return builder;
}
ConfigureAzureOptions
:
public void Configure(string name, OpenIdConnectOptions options)
{
options.ClientId = _azureOptions.ClientId;
options.Authority = _azureOptions.Authority;
options.UseTokenLifetime = true;
options.CallbackPath = _azureOptions.CallbackPath;
options.RequireHttpsMetadata = false;
options.ClientSecret = _azureOptions.ClientSecret;
options.Resource = "https://graph.microsoft.com"; // AAD graph
// Without overriding the response type (which by default is id_token), the OnAuthorizationCodeReceived event is not called.
// but instead OnTokenValidated event is called. Here we request both so that OnTokenValidated is called first which
// ensures that context.Principal has a non-null value when OnAuthorizeationCodeReceived is called
options.ResponseType = "id_token code";
// Subscribing to the OIDC events
options.Events.OnAuthorizationCodeReceived = OnAuthorizationCodeReceived;
options.Events.OnAuthenticationFailed = OnAuthenticationFailed;
}
以下是 API 项目中用于配置 Azure 选项的代码:
private class ConfigureAzureOptions : IConfigureNamedOptions<JwtBearerOptions>
{
private readonly AzureAdOptions _azureOptions;
public ConfigureAzureOptions(IOptions<AzureAdOptions> azureOptions)
{
_azureOptions = azureOptions.Value;
}
public void Configure(string name, JwtBearerOptions options)
{
// options.Audience = _azureOptions.ClientId;
options.Authority = $"{_azureOptions.Instance}{_azureOptions.TenantId}";
// The valid audiences are both the Client ID(options.Audience) and api://{ClientID}
// --->>> I've changed this to also have "https://graph.micrososft.com" but no luck
options.TokenValidationParameters.ValidAudiences = new string[] { _azureOptions.ClientId, $"api://{_azureOptions.ClientId}" }; // <<--- I've changed this to "https://graph.micrososft.com" but no luck
// If you want to debug, or just understand the JwtBearer events, uncomment the following line of code
// options.Events = JwtBearerMiddlewareDiagnostics.Subscribe(options.Events);
}
public void Configure(JwtBearerOptions options)
{
Configure(Options.DefaultName, options);
}
}
这就是我从 MVC 项目获得令牌的方式 - 权限是 api://client_id:
string userObjectID = User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier")?.Value;
//AuthenticationContext authContext = new AuthenticationContext(AzureAdOptions.Settings.Authority, new NaiveSessionCache(userObjectID, HttpContext.Session));
AuthenticationContext authContext = new AuthenticationContext(AzureAdOptions.Settings.Authority);
ClientCredential credential = new ClientCredential(AzureAdOptions.Settings.ClientId, AzureAdOptions.Settings.ClientSecret);
感谢您对此的想法和经验 - 再次感谢您的宝贵时间。
解决方案
看起来您的客户端应用正在获取 Microsoft Graph API 令牌:
options.Resource = "https://graph.microsoft.com";
访问令牌具有指定其适用的 API 的受众(aud 声明)。您的客户端应用程序需要使用 API 的客户端 ID 或应用程序 ID URI 作为资源。通过这种方式,您可以获得适用于您的 API 的访问令牌。
那里的资源选项仅限于一个 API。如果需要多个 API 的令牌,则需要为 AuthorizationCodeReceived 设置事件侦听器并使用 MSAL.NET 交换令牌的授权代码。我有一个执行此操作的示例应用程序:https ://github.com/juunas11/aspnetcore2aadauth/blob/97ef0d62297995c350f40515938f7976ab7a9de2/Core2AadAuth/Startup.cs#L58 。虽然此应用程序使用 .NET Core 2.2 和 ADAL,但使用 MSAL 的一般方法是相似的。
推荐阅读
- php - 既然 Homebrew 不再支持 --with-thread-safety,如何下载 PHP -thread safe?
- python - 在树莓派上设置 Google Assistant SDK 时遇到问题
- ios - UIImagePickerController 导入图片
- vba - excel 2016 vba检查和更改同一实例的多个窗口打开的工作表
- redux - Redux - 错误:操作必须是普通对象。使用自定义中间件进行异步操作。还原承诺
- php - 在引导轮播中导入 MYSQL 图像
- plsql - 通过将 Excel 文件作为输入对表格执行 DML
- ios - Swift 中的 Bagplot 实现
- angular - 角度分量上的 2 个形式
- php - 如何通过查询获取我的数据,以便创建具有与 OOP 相关的类的编辑函数?