MsalServiceException: AADSTS90014: отсутствует обязательное поле aud - PullRequest
1 голос
/ 30 апреля 2019

Я пытаюсь получить доступ к API-интерфейсу REST Azure через бэкэнд-приложение ASP.NET Core 2.2 (другое приложение MVC). Я хочу получить OnBehalfOf аутентификацию для API REST на основе зарегистрированного пользователя Azure AD. Я получаю эту странную ошибку.

MsalServiceException: AADSTS90014: обязательное поле 'aud' отсутствует.

Нигде в документации или сообщениях в блогах мне не удавалось найти решение или даже более тонкую обсуждаемую проблему. Ниже упомянут мой код.


public class TokenAcquisitionService : ITokenAcquisitionService
{
    private readonly UserAssertion _userAssertion;

    private readonly ConfidentialClientApplication _confidentialClientApp;

    public TokenAcquisitionService(UserContextInfo userContextInfo, MemoryTokenCache memoryTokenCache, IConfiguration configuration)
    {
        var tokenCache = memoryTokenCache.GetIDistributedCacheCacheInstance();
        var clientId = configuration.GetValue<string>("AzureAd:ClientId");
        var clientSecret = new ClientCredential(configuration.GetValue<string>("AzureAd:ClientSecret"));

        _confidentialClientApp = new ConfidentialClientApplication(clientId, userContextInfo.BaseRequestUrl, clientSecret, tokenCache, null);
        _userAssertion = new UserAssertion(userContextInfo.Token);
    }

    public async Task<string> AcquireTokenAsync()
    {
        string[] scopes = { "https://example.com/846fsd66-xxxx-yyyy-82cb-1fe40a30f00c/user_impersonation" };
        var accounts = await _confidentialClientApp.GetAccountsAsync();

        AuthenticationResult result;

        if (accounts.Any())
            result = await _confidentialClientApp.AcquireTokenSilentAsync(scopes, accounts.First());
        else
            result = await _confidentialClientApp.AcquireTokenOnBehalfOfAsync(scopes, _userAssertion);

        return result.AccessToken;
    }
}

Я использую пакет NuGet Microsoft.Identity.Client version 2.7.1 для аутентификации REST API и Microsoft.AspNetCore.Authentication.AzureAD.UI version 2.1.1 для аутентификации приложения MVC.

Обновление

Для приложения MVC я использую аутентификацию Azure Active Directory следующим образом (для моего знания она использует собственную аутентификацию с использованием cookie).

services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
            .AddAzureAD(options =>
            {
                Configuration.Bind("AzureAd", options);
            });

enter image description here

1 Ответ

0 голосов
/ 30 апреля 2019

Описание к ошибке: AADSTS90014 MissingRequiredField - This error code may appear in various cases when an expected field is not present in the credential.
Источник: Коды ошибок аутентификации и авторизации .

Поле aud предназначено для аудитории токена. И вам нужно, чтобы этот токен был предназначен для бэкэнда, на который вы его отправляете.

Взято из Введение в JSON Web Token :

Зарегистрированные претензии - Это набор предопределенных претензий, которые не являются обязательными, но рекомендуются для предоставления набора полезных, совместимых претензий. Некоторые из них: iss (эмитент), exp (срок действия), sub (субъект), aud (аудитория) и другие.

Взято из RFC 7519 - Раздел 4.1 :

Заявка "aud" (аудитория) определяет получателей, для которых JWT. Каждый принципал, предназначенный для обработки JWT, ДОЛЖЕН идентифицировать себя со значением в требовании аудитории. Если принципал, обрабатывающий претензию, не идентифицирует себя со значением в претензии "aud", когда эта претензия присутствует, то JWT ДОЛЖЕН быть отклонен. В общем случае значение "aud" - это массив строк, чувствительных к регистру, каждая из которых содержит значение StringOrURI. В особом случае, когда JWT имеет одну аудиторию, значение «aud» МОЖЕТ быть единственной чувствительной к регистру строкой, содержащей значение StringOrURI. Интерпретация ценностей аудитории, как правило, зависит от конкретного приложения. Использование этого требования НЕОБЯЗАТЕЛЬНО.

При настройке аутентификации Azure Active Directory в бэкэнде ASP.NET вы указываете аудиторию. В нашем случае код выглядит примерно так:

services.AddAuthentication(o =>
{
    o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
    options.Authority = Authority;
    options.Audience = ClientId;
    options.TokenValidationParameters = new TokenValidationParameters
    {
        SaveSigninToken = true
    };
});

Где Authority было свойством, содержащим AAD Instance + наше TenantID, а ClientID было ClientID приложения в Azure Active Directory.

При настройке MSAL для взаимодействия с аутентифицированным бэкэндом это выглядит примерно так:

MsalModule.forRoot({
  authority: 'https://login.microsoftonline.com/<TENANT>.onmicrosoft.com',
  clientID: '<CLIENT_ID_GUID>',
  protectedResourceMap: protectedResourceMap
})

Где protectedResourceMap содержит карту URL-адреса API и необходимые области действия.

...