我正在尝试通过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);
});
答案 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(受众群体)等。
“ 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和所需范围的映射。