MsalServiceException:AADSTS90014:缺少必需的字段“ aud”

时间:2019-04-30 09:11:15

标签: c# azure asp.net-core azure-active-directory msal

我正在尝试通过ASP.NET Core 2.2后端应用程序(另一个MVC应用程序)访问Azure REST api。我想基于登录的Azure AD用户获得REST api的 OnBehalfOf 身份验证。我收到这个奇怪的错误。

  

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 :(得分:0)

错误说明:AADSTS90014 MissingRequiredField - This error code may appear in various cases when an expected field is not present in the credential.
资料来源:Authentication and authorization error codes

字段aud用于令牌的预期受众。并且您需要使用它来验证令牌是发送给后端的目的。

取自JSON Web Token Introduction

  

已注册的声明-这是一组预定义的声明,不是强制性的,但建议使用,以提供一组有用的可互操作的声明。其中一些是:iss(发布者),exp(到期时间),sub(主题),aud(受众群体)等。

取自RFC 7519 - Section 4.1

  

“ aud”(听众)声明标识JWT的收件人。每个打算处理JWT的主体必须在受众声明中标识自己的价值。如果存在该声明时,处理该声明的委托人未使用“ aud”声明中的值标识自身,则必须拒绝JWT。在一般情况下,“ aud”值是一个区分大小写的字符串数组,每个字符串都包含一个StringOrURI值。在特殊情况下,当JWT有一个听众时,“ aud”值可能是一个包含StringOrURI值的区分大小写的字符串。受众价值的解释通常是特定于应用程序的。使用此声明是可选的。

在ASP.NET后端中配置Azure Active Directory身份验证时,请指定受众。在我们的例子中,代码看起来像这样:

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是Azure Active Directory中应用程序的ClientID

将MSAL配置为与经过身份验证的后端进行对话时,看起来像这样:

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

protectedResourceMap包含API URL和所需范围的映射。