我正在尝试通过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);
});
错误的描述: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(到期时间),子(主题),aud(观众)等。
“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和所需范围的映射。