c# - Microsoft Graph API授权错误: Invalid Audience

标签 c# asp.net azure oauth-2.0 microsoft-graph-api

我知道这是一个很长的问题,但如果有人可以与我分享他们的想法或经验,我将非常感激,因为我已经解决这个问题几天了,现在正在尝试很多事情。我有一个 ASP Net Core 3.1 Web API 应用程序和一个 ASP.NET Core 3.1 MVC 应用程序。

两者均已在 Azure AD 中注册。 API 项目应该根据从 MVC 项目接收到的请求负载创建日历事件。我按照 this link here 中的 Microsoft 说明进行操作

但是,一旦 API 项目对 Microsoft Graph 进行调用,就会失败并出现以下错误:

"code": "InvalidAuthenticationToken",
"message": "Access token validation failure. Invalid audience.",

我在这里输入了最小值以提供更多信息,但整个示例可以从 the link above 下载。 .

ASP.NET Core 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;
}

配置AzureOptions:

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 项目获取 token 的方式 - 权限是 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 token :

options.Resource = "https://graph.microsoft.com"; 

访问 token 有一个受众(aud 声明),用于指定它的 API 用途。 您的客户端应用程序需要使用 API 的客户端 ID 或应用程序 ID URI 作为资源。 这样您就可以获得适用于您的 API 的访问 token 。

那里的资源选项仅限于一个 API。 如果您需要多个 API 的 token , 您需要为 AuthorizationCodeReceived 设置事件监听器,并使用 MSAL.NET 将授权代码交换为 token 。 我有一个示例应用程序可以执行此操作:https://github.com/juunas11/aspnetcore2aadauth/blob/97ef0d62297995c350f40515938f7976ab7a9de2/Core2AadAuth/Startup.cs#L58 。 虽然此应用使用 .NET Core 2.2 和 ADAL,但 MSAL 的一般方法类似。

关于c# - Microsoft Graph API授权错误: Invalid Audience,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61492479/

相关文章:

.net - 部署在本地 IIS 中时,azure 消息传递服务未接收消息

linux - 在一个 Web 应用程序下托管两个网站 - Azure 服务

c# - 仅处理消息队列中的部分消息

c# - 如何在我想使用 NUnit 测试的方法中模拟方法调用?

c# - Silverlight,连接到不同服务器上的多个数据库

c# - 从分隔的数据库字符串字段中选择多选列表框中的项目

Azure管道托管代理,指定镜像版本

c# - Web API 2 路由属性不起作用

javascript - 如何将金额类型更改为数字类型以在javascript中执行算术运算

c# - Html.TextBoxFor NullReferenceException 使用 Razor 语法