Ошибка авторизации Microsoft Graph API: недопустимая аудитория - PullRequest
0 голосов
/ 29 апреля 2020

Я понимаю, что это длинный вопрос, но я был бы очень признателен, если бы кто-нибудь поделился со мной своими мыслями или опытом, так как я уже несколько дней пытаюсь это сделать. У меня есть приложение asp net core 3.1 web API и приложение ASP. NET Core 3.1 MVC.

Оба были зарегистрированы в Azure нашей эры. Предполагается, что проект API создает события календаря на основе полезной нагрузки запроса, которую он получает от проекта MVC. Я следую инструкциям Microsoft от по этой ссылке здесь

Но как только проект API выполняет вызов для Microsoft Graph, он завершается неудачно со следующей ошибкой:

"code": "InvalidAuthenticationToken",
"message": "Ошибка проверки маркера доступа. Недопустимая аудитория.",

Я добавляю минимум здесь, чтобы предоставить больше информации, но весь образец можно загрузить по по ссылке выше .

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 Ядро 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);

Я ценю ваши мысли и опыт в это - еще раз спасибо за ваше время.

1 Ответ

1 голос
/ 29 апреля 2020

Похоже, что ваше клиентское приложение приобретает токен API Microsoft Graph:

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

Токен доступа имеет аудиторию (утверждение aud), которая указывает, для какого API он предназначен. Ваше клиентское приложение должно использовать идентификатор клиента API или URI идентификатора приложения в качестве ресурса. Таким образом, вы получаете токен доступа, предназначенный для вашего API.

Параметр Resource там ограничен одним API. Если вам нужны токены для нескольких API, вам нужно настроить прослушиватель событий для AuthorizationCodeReceived и использовать MSAL. NET для обмена кодом авторизации для токенов. У меня есть пример приложения, которое делает это: https://github.com/juunas11/aspnetcore2aadauth/blob/97ef0d62297995c350f40515938f7976ab7a9de2/Core2AadAuth/Startup.cs#L58. Это приложение использует. NET Core 2.2 и ADAL, но общий подход с MSAL будет аналогичным.

...