Gurvir
Gurvir

Reputation: 23

DocuSign API JWT Issue (Python)

I seem to be having trouble getting authentication to work correctly when using the jwt method.

Here's the request built for authorizing with the application

        uri = api_client.get_authorization_uri(                                                                            
            client_id       = DOCUSIGN_APP_INTEGRATION_KEY,                                                       
            redirect_uri    = WEBHOOK_URL,                                          
            scopes          = ["signature","impersonation"],                                                               
            response_type   = 'code',                                                                                      
        )                                                                                                                  
        uri +="&prompt=login"       

And heres the webhook to then get the token

            api_client  = ApiClient(oauth_host_name = settings.DOCUSIGN_OAUTH_HOST_NAME)                                   
                                                                                                                           
            # Get account id for authed user                                                                               
            xyz = api_client.generate_access_token(                                                                        
                client_id           = DOCUSIGN_APP_INTEGRATION_KEY,                                               
                client_secret       = DOCUSIGN_CLIENT_SECRET_KEY,                                                 
                code                = code,                                                                                
            )                                                                                                              
                                                                                                                           
            resp = api_client.get_user_info(access_token = xyz.access_token)                                               
                                                                                                                           
                                                                                     
            acc_id = resp.sub                                                                                     
            base_uri = ''                                                                                                  
            for account in resp.accounts:                                                                                  
                if account.is_default:                                                                                     
                    base_uri = account.base_uri                                                                                   
                    break                                                                                                  
                                                                                                                           
            token = api_client.request_jwt_user_token(                                                                     
                client_id           = DOCUSIGN_APP_INTEGRATION_KEY,                                               
                user_id             = acc_id,                                                                              
                oauth_host_name     = api_client.get_oauth_host_name(),                                                    
                private_key_bytes   = DOCUSIGN_PRIVATE_KEY,                                                       
                expires_in          = 3600,                                                                                
            )
            
            # Save token.access_token, and base_uri for use elsewhere
            ...               

I've also tried using the account id found from resp.accounts[0].account_id (Since theres only one account for the user) but that fails on request_jwt_user_token with this error

HTTP response body: b'{"error":"invalid_grant","error_description":"user_not_found"}

This all works fine and well, but then when I attempt to create an envelope elsewhere using the token like so

    # Setup api client with token                                                                                      
        api_client = ApiClient()                                                                                           
        api_client.host = api_base_path # set to https://demo.docusign.net/restapi                                                                                  
        api_client.set_default_header("Authorization", "Bearer " + token)                                                  
        envelope_api = EnvelopesApi(api_client)                                                                            
                                                                                                                           
        try:                                                                                                               
            envelope_resp = envelope_api.create_envelope(                                                                  
                DOCUSIGN_API_USER_KEY,                                                                            
                envelope_definition=envelope_definition                                                                    
            )                                                                                                              
        except ApiException as e:
            ...                                                                                         
                            

I receive this error

HTTP response body: b'{"errorCode":"USER_DOES_NOT_BELONG_TO_SPECIFIED_ACCOUNT","message":"The specified User is not a member of the specified Account."}'

I've also tried to use acc_id instead of the api users key when creating the envelope, but that gives this error:

HTTP response body: b'{"errorCode":"PARTNER_AUTHENTICATION_FAILED","message":"The specified Integrator Key was not found or is disabled. Invalid account specified for user."}'

This is all done through the library provided docusign-esign for python.

Not quite sure where to go from here, but any help is appreciated!

Upvotes: 1

Views: 1247

Answers (1)

Inbar Gazit
Inbar Gazit

Reputation: 14015

Here is some information that may help.

In DocuSign you have accounts and memberships that are part of the accounts - users. So, a userId is one thing (GUID) and an accountID is another thing (GUID). You can only access envelopes from an account to which you are member. when using JWT, you have to provide the userId to get the access token. The calls are them made by impersonating this user. If you try to access an envelope (or anything) from an account to which said user has no membership - you get the error you got.

One last thing, please ensure everything is done in the same anv. Meaning, if Oauth is done in demo/developer (account-d.docusign.com) then the API calls are made to the same env (demo.docusign.net). If you use account.docusign.com (production) then the API calls need to be to the correct URL which will NOT be demo.docusign.net (but could be na3.docusign.net or eu1.docusign.net etc.)

Upvotes: 1

Related Questions