Обмен jwt на токен доступа возвращает ошибку invalid_grant - PullRequest
0 голосов
/ 24 мая 2018

Я пытаюсь реализовать аутентификацию интеграции служб - согласие администратора для моего приложения.Вот как я создал jwt:

class Program
{
    static void Main(string[] args)
    {
        #region Test

        string integratorKey = "integratorKey ";
        string userId = "userId ";
        string serverAddress = "serverAddress";
        string scope = "signature";
        string key = @"C:\Users\Tester\Desktop\privatekey.txt";

        // JWT Header
        // The header specfies the token type and the signature algorithm
        var jwtHeader = new JwtHeader
        {
            { "typ ", "JWT "},
            { "alg", "RS256"},
        };

        // JWT Body
        // The body specfies the account and user id granting consen
        var jwtPayload = new JwtPayload
        {
           { "iss ", integratorKey},
           { "sub", userId},
           { "iat", DateTimeOffset.UtcNow.ToUnixTimeSeconds()},
           { "exp", DateTimeOffset.UtcNow.AddHours(1).ToUnixTimeSeconds()},
           { "aud", serverAddress},
           { "scope", scope}
        };

        // JWT Signature
        // The body contains the result of signing the base64url-encoded header and body
        string pemKey = File.ReadAllText(key);
        var rsa = CreateRSAKeyFromPem(pemKey);
        RsaSecurityKey rsaKey = new RsaSecurityKey(rsa);

        var jwtSecurityToken = new JwtSecurityToken(jwtHeader, jwtPayload);
        jwtSecurityToken.SigningKey = rsaKey;

        // Token to String so you can use it in your client
        var jwtHandler = new JwtSecurityTokenHandler();
        var tokenString = jwtHandler.WriteToken(jwtSecurityToken);
        #endregion
    }

    public static RSA CreateRSAKeyFromPem(string key)
    {
        TextReader reader = new StringReader(key);
        PemReader pemReader = new PemReader(reader);

        object result = pemReader.ReadObject();

        if (result is AsymmetricCipherKeyPair)
        {
            AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)result;
            return DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)keyPair.Private);
        }
        else if (result is RsaKeyParameters)
        {
            RsaKeyParameters keyParameters = (RsaKeyParameters)result;
            return DotNetUtilities.ToRSA(keyParameters);
        }

        throw new Exception("Unepxected PEM type");
    }
}

Я проверил токен, сгенерированный этим кодом на jwt.io, и все выглядит хорошо.Однако, когда я пытался обменять сгенерированный jwt на код доступа с помощью Postman, я всегда получал «invalid_grant», вот как я сделал запрос в почтальоне:

POST https://account-d.docusign.com/oauth/token
-Headers: Content-Type application/x-www-form-urlencoded

-Body: grant_type urn:ietf:params:oauth:grant-type:jwt-bearer assertion [Generated jwt]

Я даже пытался поставить

Headers: Authorization Basic b64encoded(integratorKey:secretKey) 

тоже, но все равно не повезло.

Не могли бы вы указать, что я здесь делаю не так?Спасибо:)

1 Ответ

0 голосов
/ 24 мая 2018

Хорошо, мне удалось выяснить, в чем дело, и теперь я могу получить токен доступа в Почтальоне.3 вещи, которые я изменил, чтобы сделать эту работу:

  1. Когда я авторизую приложение с портала организации, я назначил приложение неверному ключу интегратора, поэтому мне нужно изменить его, чтобы он указывал направильный.

  2. Я нашел в C # SDK код для генерации jwt, поэтому использовал его, чтобы убедиться, что созданный jwt принят DocuSign:

    static void Main(string[] args)
    {
        string integratorKey = "integratorKey ";
        string userId = "userId ";
        string serverAddress = "account-d.docusign.com";
        string scope = "signature impersonation";
        string privateKeyFilename = @"C:\Users\Tester\Desktop\privatekey.txt";
    
        JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
    
        SecurityTokenDescriptor descriptor = new SecurityTokenDescriptor()
        {
            IssuedAt = DateTime.UtcNow,
            Expires = DateTime.UtcNow.AddHours(1)
        };
    
        descriptor.Subject = new ClaimsIdentity();
        descriptor.Subject.AddClaim(new Claim("scope", scope));
        descriptor.Subject.AddClaim(new Claim("aud", serverAddress));
        descriptor.Subject.AddClaim(new Claim("iss", integratorKey));
    
        if (userId != null)
        {
            descriptor.Subject.AddClaim(new Claim("sub", userId));
        }
    
        if (privateKeyFilename != null)
        {
            string pemKey = File.ReadAllText(privateKeyFilename);
            var rsa = CreateRSAKeyFromPem(pemKey);
            RsaSecurityKey rsaKey = new RsaSecurityKey(rsa);
            descriptor.SigningCredentials = new SigningCredentials(rsaKey, SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.HmacSha256Signature);
        }
    
        var token = handler.CreateToken(descriptor);
        string jwtToken = handler.WriteToken(token);
    }
    
    public static RSA CreateRSAKeyFromPem(string key)
    {
        TextReader reader = new StringReader(key);
        PemReader pemReader = new PemReader(reader);
    
        object result = pemReader.ReadObject();
    
        if (result is AsymmetricCipherKeyPair)
        {
            AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)result;
            return DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)keyPair.Private);
        }
        else if (result is RsaKeyParameters)
        {
            RsaKeyParameters keyParameters = (RsaKeyParameters)result;
            return DotNetUtilities.ToRSA(keyParameters);
        }
    
        throw new Exception("Unepxected PEM type");
    }
    
  3. После того, как я внес изменения 1 и 2, у меня все еще есть ошибка в Почтальоне: "accord_required".Оказывается, я должен добавить URI перенаправления к своему ключу интегратора, затем перейдите по этому URL:

    SERVER/oauth/auth?response_type=code&scope=signature%20impersonation&client_id=CLIENT_ID&redirect_uri=https://docusign.com
    

и нажмите «Предоставить».

Надеюсь, это поможет.

...