Я получаю сообщение об ошибке (упомянутое ниже), когда пытаюсь использовать токен пользователя Cortana Bot (который является токеном Graph) для создания токена «от имени» для другого приложения-потребителя веб-API с использованием ClientAssertionCertificate
/ ClientCredential
target другому потребляющему веб-API, передав его AppId
как ResourceId
и userAssertion
, сгенерированный с помощью токена пользователя Cortana Bot.
При проверке наших настроек Bot AAD он настроен с другим потребляющим веб-API (API B) в качестве допустимого приложения вместе с приложением Graph. Нужно ли нам делать какие-либо дополнительные настройки в AAD, чтобы получить этот токен от имени?
AADSTS50013: Assertion contains an invalid signature.
[Reason - The provided signature value did not match the expected signature value.,
Thumbprint of key used by client: '9DB0B05B5D70DD7901FB151A5F029148B8CC1C64',
Found key 'Start=11/11/2018 00:00:00,
End=11/11/2020 00:00:00'
]
Trace ID: a440869f-b8f5-4d87-ba1a-6bd8dd7ba200
Correlation ID: 651e1fa8-2069-4489-a687-e68e5206e193
Timestamp: 2019-01-02 07:14:45Z
Ниже приведен поток и пример кода, как мы пытаемся получить токен от имени для другого потребляющего веб-API (API B).
Шаги потока:
- Кортана просит пользователя войти в систему
- Вход пользователя в Кортану
- Кортана отправляет этот токен пользователя (созданный таргетинг для использования https://graph.microsoft.com в качестве аудитории) в Microsoft. API-интерфейс Bot Framework
- API Microsoft Bot Framework проверяет и хочет использовать этот токен для вызова другого веб-API (который называется API B).
- Поскольку этот токен пользователя Cortana нельзя использовать напрямую, его необходимо сгенерировать как токен от имени для API B из Microsoft Bot Framework API.
Ниже приведен пример кода, который используется для создания токена от имени из API Microsoft Bot Framework:
public async Task<string> GetOnBehalfOfTokenAsync(string authority, string resource, string scope = "", string token = "") { AuthenticationResult output; var clientId = ConfigurationManager.AppSettings["API-B-ClientId"]; // Read certificate which can be used for getting token to API B using ClientAssertionCertificate // GetCert() is used to get the Certificate based on Thumbprint configured in Web.config file. var certificate = this.GetCert(); // 'authority' is https://login.microsoftonline.com/{tenant id} var authContext = new AuthenticationContext(authority); var cllientCertificateCredential = new ClientAssertionCertificate(clientId, certificate); // 'token' is the user token which was received from Cortana. var userAssertion = (!string.IsNullOrWhiteSpace(token)) ? new UserAssertion(token, "urn:ietf:params:oauth:grant-type:jwt-bearer", TokenHelper.ExtractUserInfoFromAuthToken(token, "upn")) : null; try { // 'resource' is the Resource Id of API B // if UserAssertion is null then get token with ClientAssertionCertificate else get // on-behalf-of token using UserAssertion and ClientAssertionCertificate if (userAssertion == null) { output = await authContext .AcquireTokenAsync(resource, cllientCertificateCredential) .ConfigureAwait(false); } else { output = await authContext .AcquireTokenAsync(resource, cllientCertificateCredential, userAssertion) .ConfigureAwait(false); } } catch (Exception ex) { logger.log("Error acquiring the AAD authentication token", ex); } return output.AccessToken; }
Получение исключения, о котором говорилось выше на этом шаге:
output = await authContext .AcquireTokenAsync(resource, cllientCertificateCredential, userAssertion) .ConfigureAwait(false);