От имени проблемы с токеном (AADSTS50013: утверждение содержит недопустимую подпись)

Я получаю сообщение об ошибке (упомянуто ниже), когда пытаюсь использовать токен пользователя Cortana Bot (который является токеном Graph) для создания токена "от имени" для другого потребляющего приложения Web API, использующего ClientAssertionCertificate / ClientCredential нацелены на другой потребительский веб-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).

Этапы потока:

  1. Кортана просит пользователя Войти
  2. Вход пользователя в Cortana
  3. Cortana отправляет этот маркер пользователя (сгенерированный таргетинг для использования https://graph.microsoft.com/ качестве аудитории) в API Microsoft Bot Framework
  4. Microsoft Bot Framework API проверяет и хочет использовать этот токен для вызова другого Web API (который называется API B).
  5. Поскольку этот токен пользователя Cortana нельзя использовать напрямую, его необходимо сгенерировать как токен от имени пользователя API B из Microsoft Bot Framework API.
  6. Ниже приведен пример кода, который используется для создания токена от имени от Microsoft Bot Framework API:

    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;
    }
    
  7. Получение исключения, которое было упомянуто выше на этом шаге:

    output = await authContext
       .AcquireTokenAsync(resource, cllientCertificateCredential, userAssertion)
        .ConfigureAwait(false);
    

2 ответа

Решение

Мы могли бы решить эту проблему, настроив нашу зависимую область действия "user_impersonation" API (API B) для конфигурации канала Cortana для нашего бота. С этим изменением конфигурации нам не нужно генерировать токен On-Behalf-Of для API B из нашего приложения Microsoft Bot.

Спасибо всем, кто поддержал, чтобы обеспечить решения для этой темы...

Насколько я понимаю: сначала вы получаете токен пользователя из своего API-интерфейса msg для Cortana access; а затем вы хотите использовать токен пользователя для генерации токена OBO в Microsoft Bot Framework API; наконец, вы хотите использовать токен OBO для доступа к API B из Microsoft Bot Framework API.

Вы хотите получить токен OBO в Microsoft Bot Framework API, вы должны использовать идентификатор API и секрет, для этого я никогда не пробовал этого.

Со своей стороны я использую конечную точку v1, я создаю два API (API A и B), и мой поток таков: во-первых, мое приложение запрашивает token1 для API A;

Затем используйте token1 для запроса OBO token2 для API B у API A;

Наконец, используйте OBO token2, чтобы запросить OBO token3 для API aad graph из API B.

О OBO в конечной точке v1 читайте по ссылке1.

Для OBO в конечной точке v2, пожалуйста, прочитайте ссылку 2.

Другие вопросы по тегам