Почему мой токен / утверждение JWT получает ответ «Недопустимый токен» от службы Einstein OAuth?

#.net #api #jwt #salesforce #salesforce-einstein

#.net #API #jwt #salesforce #salesforce-einstein

Вопрос:

Я следую разреженным инструкциям, изложенным здесь: https: //metamind.readme.io/docs/generate-an-oauth-token-using-your-key

Мне нужно иметь возможность генерировать токен-носитель, чтобы иметь возможность доступа к службам Einstein непосредственно из .net, и, в частности, .net 4.5.

В качестве поддержки RSACryptoServiceProvider.ImportRSAPrivateKey недоступен до .net 5, я преобразовал свой pem-файл (загруженный из salesforce) в формат xml (используя https://superdry.apphb.com/tools/online-rsa-key-converter ) и я использую это, чтобы подписать утверждение JWT. Я получаю закодированное утверждение, но когда я отправляю его в https://api.einstein.ai/v2/oauth2/token служба, я продолжаю получать сообщение «Недопустимый токен».

Вот мой код:

             Claim[] claims = new[] {
                new Claim(JwtRegisteredClaimNames.Sub, this.Username),
                new Claim(JwtRegisteredClaimNames.Aud, this.Endpoint.ToString()),
                new Claim(JwtRegisteredClaimNames.Exp, ((int)expiryUnixTimeStamp).ToString())
            };

            RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
            provider.FromXmlString(this.RsaXmlString);
            RsaSecurityKey rsaSecurityKey = new RsaSecurityKey(provider);
            SigningCredentials signingCredentials = new SigningCredentials(rsaSecurityKey, SecurityAlgorithms.RsaSha256);

            JwtSecurityToken jwtSecurityToken = new JwtSecurityToken(
                new JwtHeader(signingCredentials),
                new JwtPayload(claims)
            );
            
            string jwtToken = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
  

Я проверил все свои параметры. Я могу использовать один и тот же ключ pem и имя пользователя для успешного создания токена-носителя, используя интерфейс браузера, так почему же он терпит неудачу в коде?

Ответ №1:

Ответ на эту проблему заключается в том, чтобы не генерировать JwtPayload из массива утверждений. Он компилируется, но конструктор утверждений принимает только строковые значения. Существует аргумент ValueType , но это тоже строка, содержимое которой недокументировано. Я не смог найти значения для ValueType, которое позволило бы мне указать значение ‘exp’ как целое число. Итак, проблема заключалась в том, что моя метка unixtimestamp сериализовалась как строка, и это делало утверждение недействительным.

Решение: загрузка JwtPayload.Метод Add принимает объект вместо строки…

 JwtPayload jwtPayload = new JwtPayload();
jwtPayload.Add(JwtRegisteredClaimNames.Sub, this.Username);
jwtPayload.Add(JwtRegisteredClaimNames.Aud, this.Endpoint.ToString());
jwtPayload.Add(JwtRegisteredClaimNames.Exp, (int)expiryUnixTimeStamp);

JwtSecurityToken jwtSecurityToken = new JwtSecurityToken(
    new JwtHeader(signingCredentials),
    new JwtPayload(jwtPayload)
);