Передача токена из аутентифицированного приложения в другой API для использования потока OBO в Graph API
У нас есть одно приложение, использующее MSAL и создающее токен с помощью Azure AD. Нам нужно, чтобы это приложение вызывало другой API, и мы передаем текущий токен. Что все хорошо. У нас есть два разных приложения, и я включу некоторый код, чтобы показать, как аудитория (другой идентификатор клиента) может аутентифицироваться
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(opt =>
{
opt.Audience = Configuration["AzureAd:ResourceId"];
opt.Authority = $"{Configuration["AzureAd:Instance"]}/{Configuration["AzureAd:TenantId"]}";
opt.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidAudiences = new string[] { "e8zzz-3304-43e0-aaaa-zzzzzzzzz" }
};
});
Так что аутентификация не проблема. Мы используем GraphServiceClient для доступа к API графа, но токен, который мы получаем из заголовка авторизации, является токеном, переданным из другого приложения, и имеет идентификатор клиента, привязанный к другому приложению. Все работает нормально, пока не дойдет до строки с AcquireTokenAsync, и в возвращаемой проблеме не будет указано: «Аудитория утверждений не соответствует клиентскому приложению, представляющему утверждение. Аудитория в утверждении была «{идентификатор другого приложения}», а ожидаемая аудитория — « {идентификатор приложения API}» или один из Uris приложения этого приложения с идентификатором приложения «{идентификатор приложения API}» (приложение API). Нижестоящий клиент должен запросить токен для ожидаемой аудитории (приложение, которое сделало запрос OBO), и это приложение должно использовать этот токен в качестве утверждения».
public async Task<GraphServiceClient> GetAuthenticatedClient()
{
var httpContext = this.httpContextAccessor.HttpContext;
if (httpContext != null)
{
StringValues authorizationToken;
httpContext.Request.Headers.TryGetValue("Authorization", out authorizationToken);
var authHeader = authorizationToken.FirstOrDefault();
if (authHeader != null && authHeader.StartsWith("bearer", StringComparison.OrdinalIgnoreCase))
{
var token = authHeader.Substring("Bearer ".Length).Trim();
var clientCredential = new ClientCredential(_authOptions.ClientId, _authOptions.ClientSecret);
var authenticationContext = new AuthenticationContext($"https://login.microsoftonline.com/{_authOptions.TenantId}");
var authenticationResult = await authenticationContext.AcquireTokenAsync("https://graph.microsoft.com", clientCredential, new UserAssertion(token));
var delegateAuthProvider = new DelegateAuthenticationProvider((requestMessage) =>
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", authenticationResult.AccessToken);
return Task.FromResult(0);
});
return new GraphServiceClient(delegateAuthProvider);
}
}
throw new UnauthorizedAccessException("Invalid User token.");
}
Другой момент заключается в том, что у меня ограниченный доступ к Azure AD, кроме чтения. Другая группа контролирует это. Это своего рода политика, поэтому я не могу обновлять вещи, чтобы попробовать что-то самостоятельно, и любые изменения занимают как минимум день.
Я также установил известные приложения в манифесте API.
Я, вероятно, «мог бы» использовать учетные данные клиента из другого приложения только для того, чтобы увидеть, как оно работает, но это не очень хороший ответ, поскольку мы не хотим знать эти учетные данные для других приложений. Конечно, это делается и Я упускаю что-то очевидное. Большое спасибо заранее .. Надеюсь, во всяком случае, это пригодится кому-то еще в будущем.
1 ответ
Не могли бы вы попробовать передать токен из приложения в API в почтальоне и посмотреть, будет ли получен правильный идентификатор приложения.
Вы также можете попробовать этот пример для вызова веб-API в веб-приложении с помощью Azure AD и OpenID Connect .