'"no_valid_keys_or_signatures" Error Calling DocuSign API through Java SDK for OAuth 2.0 Authentication

I am upgrading our application's authentication method into the DocuSign API from the DocuSign Legacy Authentication to the JWT Grant OAuth 2.0 Authentication.

I am receiving the following error when making the Java SDK API call:

Caused by: com.docusign.esign.client.ApiException: Error while requesting server, received a non successful HTTP code 400 with response Body: '{"error":"invalid_grant","error_description":"no_valid_keys_or_signatures"}' at com.docusign.esign.client.ApiClient.requestJWTUserToken(ApiClient.java:866)

I am performing this from the DocuSign Demo Environment and am using the docusign-esign-java jar - version 3.12.0. Here is the salient code snippet:

    private OAuthToken getOAuthToken(final String integratorKey, final String userId, final String rsaPrivateKey) {

    final ApiClient apiClient = new ApiClient();
    OAuthToken oAuthToken = new OAuthToken();

    final List<String> scopes = Arrays.asList(Scope_SIGNATURE, Scope_IMPERSONATION);

    try {
        // call failing here on apiClient.requestJWTUserToken(...)
        oAuthToken = apiClient.requestJWTUserToken(integratorKey, userId, scopes, rsaPrivateKey.getBytes(), 10000);
    }
    catch (IllegalArgumentException | IOException e) {
        this.exceptionService.handleApiException("requestJWTUserToken", new ApiException(null, e, 500, null, null));
    }
    catch (final ApiException e) {
        this.exceptionService.handleApiException("requestJWTUserToken", e);
    }

    return oAuthToken;
}

Now as far as the parameters go, I am using the Integration Key for my specific app from the Apps and Keys page:

DocuSign Demo Apps & Keys

As far as the userId is concerned, I am using the API Username from the Admin screen below related to the user that is deemed as the application user:

DocuSign Demo User

Note that I have followed the instructions found here to request for application consent for this particular user above. This process was successful.

Concerning the scopes parameters, I am passing the Signature and Impersonation scopes as evidenced in the code snippet.

As for the rsaPrivateKey parameter I am using the generated one that I copied during the creation on the following page:

DocuSign Demo Specific App

Note that my User Application Authentication method on that screen is Authorization Code Grant and I set up the redirect URI as shown.

Finally, the last parameter is for the JWT assertion time and is set at 10000 seconds currently.

Now when I pause at a breakpoint just before the failing line is called I see that all of my parameters are defined as expected from the explanation above.

Could someone shed some light on what I may be doing wrong?

Any help is greatly appreciated!



Solution 1:[1]

After a bit more discussion with a colleague and examining the Quickstart Application, the problem was rather trivial. If you look in the code snippet I have above you will see this:

final ApiClient apiClient = new ApiClient();

As mentioned, I'm attempting this in the demo environment. Well, apparently the default constructor populates the basePath in the ApiClient object with the Prod basePath...hence the ApiClient was set up with the wrong basePath property. If I change the line above to instantiate the ApiClient with the basePath from the Demo Environment (pulled from a java property) then all is well:

final ApiClient apiClient = new ApiClient(this.docusignProperties.getRestApiUrl());

Onward!

Solution 2:[2]

On my case i have generate the JWT token from the website jwt.io but i all the time have the Error no_valid_keys_or_signatures and after many test i have found the error :

For the "exp", i have put an epoch (https://www.epochconverter.com/) value to too far in time (year 2050)

{
"iss":"ea670856-xxxx-xxxx-xxxx-80560d323639",
"sub":"917c9fc5-xxxx-xxxx-xxxx-87e7ede3b8ac",
"aud":"account-d.docusign.com",
"iat": 1628496664,
"exp": 1912493464,
"scope":"signature impersonation"
}

In postman i use the following parameters :

  1. Select “Post”
  2. Put the API Value : https://account-d.docusign.com/oauth/token
  3. Click on the “Body” section
  4. Add the key grant_type
  5. Add the value urn:ietf:params:oauth:grant-type:jwt-bearer for the key grant_type
  6. Add the key assertion
  7. Add the generate value from the site jwt on the previous steps

Postman screenshot

Solution 3:[3]

I got DocuSign's 401 error (the status wasn't 400 for me) after I tried to use an integration that was moved from demo to production. I missed updating the "aud" value to the production url. It is really easy to miss little things like this.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 risingTide
Solution 2 Etienne Kaiser
Solution 3 T Beatty