简体   繁体   English

Microsoft Graph API 授权错误:无效的受众

[英]Microsoft Graph API authorization error: Invalid Audience

I understand it's a long question but I would really appreciate it if anyone could share their thoughts or experience with me as I've been around this for a few days now trying lots of things.我知道这是一个很长的问题,但如果有人能与我分享他们的想法或经验,我将不胜感激,因为我已经在这方面工作了几天,现在正在尝试很多事情。 I'm having an asp net core 3.1 web API application and an ASP.NET Core 3.1 MVC application.我有一个 asp net core 3.1 web API 应用程序和一个 ASP.NET Core 3.1 MVC 应用程序。

Both have been registered in Azure AD.两者都已在 Azure AD 中注册。 The API project is supposed to create calendar events based on the request payload it receives from the MVC project. API 项目应该根据从 MVC 项目接收到的请求负载创建日历事件。 I am following the Microsoft instructions from this link here我正在按照此处链接中的 Microsoft 说明进行操作

But once the API project makes a call against the Microsoft Graph, it fails with the following error:但是一旦 API 项目对 Microsoft Graph 进行调用,它就会失败并出现以下错误:

"code": "InvalidAuthenticationToken", "code": "InvalidAuthenticationToken",
"message": "Access token validation failure. Invalid audience.", "message": "访问令牌验证失败。无效的受众。",

I'm putting in the minimum here to provide some more info but the whole sample can be downloaded from the link above .我在这里提供了更多信息,但可以从上面的链接下载整个示例。

ASP.NET Core MVC Startup.cs : 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 project AddAzureAd function: ASP.NET 核心 MVC 项目AddAzureAd function:

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 : 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;
}

And here's the code from the API project to configure Azure Options:这是 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);
    }
}

This is how I gain a token from the MVC project - the authority is the api://client_id:这就是我从 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);

I appreciate your thoughts and experience on this - thanks again for your time.感谢您对此的想法和经验 - 再次感谢您的宝贵时间。

Looks like your client app is acquiring a Microsoft Graph API token:看起来您的客户端应用正在获取 Microsoft Graph API 令牌:

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

An access token has an audience (aud claim) that specifies what API it is meant for.访问令牌的受众(aud 声明)指定了它的用途 API。 Your client app needs to use your API's client id or application ID URI as the resource.您的客户端应用程序需要使用 API 的客户端 ID 或应用程序 ID URI 作为资源。 This way you get an access token that is meant for your API.通过这种方式,您可以获得一个适用于您的 API 的访问令牌。

The Resource option there is limited to one API.那里的资源选项仅限于一个 API。 If you need tokens for multiple APIs, you'll need to setup an event listener for AuthorizationCodeReceived and use MSAL.NET to exchange the authorization code for tokens.如果需要多个 API 的令牌,则需要为 AuthorizationCodeReceived 设置事件侦听器并使用 MSAL.NET 交换令牌的授权代码。 I have a sample app that does this: https://github.com/juunas11/aspnetcore2aadauth/blob/97ef0d62297995c350f40515938f7976ab7a9de2/Core2AadAuth/Startup.cs#L58 .我有一个示例应用程序可以执行此操作: https://github.com/juunas11/aspnetcore2aadauth/blob/97ef0d62297995c350f40515938f7976ab7a9de2/Core2AadAuth/Startup.cs#L58 This app uses .NET Core 2.2 and ADAL though, but the general approach with MSAL would be similar.这个应用程序虽然使用 .NET Core 2.2 和 ADAL,但使用 MSAL 的一般方法是相似的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM