My DocuSign App failed the "Go Live Review" due to me not using OAuth 2.0 authentication.
I have now read the documentation on how to "Get an access token with JWT Authentication" below:
https://developers.docusign.com/platform/auth/jwt/jwt-get-token/
Following this documentation I am able to get the JWT using jwt.io as suggested.
The Verified Signature code from jwt.io is then used to exchange for an DocuSign access_token using POSTMAN.
All this works as expected.
After some time the Verified Signature optained from jwt.io expires and calling https://account-d.docusign.com/oauth/token from POSTMAN results in this error:
{
"error": "invalid_grant",
"error_description": "expired_grant"
}
To fix this, I simply go to jwt.io and update the Payload section with new values for "iat" and "ext" and a new Verified Signature is obtained and copied in to POSTMAN for new request of access_token.
My question:
How to solve this expiring issue as DocuSign endpoint does not provide a refresh_token ?
It must be possible to somehow "renew" the Verified Signature as DocuSign endpoint requires this updated value for the field : "assertion" in POSTMAN.
I have tried to construct the three values separated by a period in the Verified Signature manually by base64 encoding, but I can´t figure out how to get the final RSASHA256 value in the Verified Signature.
I have seen the documentation for "Migrate to OAuth 2.0 using the DocuSign eSignature C#SDK" on this link :
https://developers.docusign.com/platform/auth/oauth2-requirements-migration/
Please note that I am not a developer and maybee the solution to my question is obvious for real developers - but I need a bit of help to solve this as I do not work in development-tool as shown on the video.
Please help...
How to solve this expiring issue as DocuSign endpoint does not provide a refresh_token?
The best is to create a new JWT for each OAuth call to DocuSign--and use software, not a website, to do so.
Note: Only obtain a new access token (by sending a fresh JWT) when the old access token has expired or is about to expire.
The DocuSign SDKs include functions to create a JWT. All of the SDKs are open source, so if you don't want to use the SDK as a whole, you can copy out the functions' implementations.
This would depend on what language your app is written in or what kind of tool it's built on. Generally, most programming languages have libraries that can generate the JWT for you without having to use jwt.io manually.
Does your app only make API calls via postman? This post might be helpful for you. It shows how to set up a pre-request script to generate the JWT
Related
Client error: `POST https://demo.docusign.net/restapi/v2.1/accounts/74724935-eef9-4006-a4be-05c65feb49fc/envelopes` resulted in a `401 Unauthorized` response:
{"errorCode":"PARTNER_AUTHENTICATION_FAILED","message":"The specified Integrator Key was not found or is disabled.
You didn't provide your code or any information at all about how you are making the API call.
But this error means you didn't set Auth correctly.
You need to provide a security header with your token that has not expired and is valid for this environment.
Suggest you read how to use OAuth with DocuSign.
There's a few things you can check listed here: https://www.docusign.com/blog/dsdev-from-the-trenches-may-2020
Is your integration key live?
Can you make calls in the Demo environment successfully?
How is your x-docusign-authentication header defined? Please don't provide sensitive info like your password or your the key itself, just the format with the key credentials replaced with generic text
Are you using an SDK or calling the API directly?
I am using the Microsoft Graph API along with Microsoft Authentication Library (MSAL) to acquire access tokens and I can successfully retrieve the access token, id token and refresh token. I can also successfully validate the id token. However, I cannot do the same for the access token as I'm getting this error:
raise InvalidSignatureError('Signature verification failed')
jwt.exceptions.InvalidSignatureError: Signature verification failed
I've reviewed as best as I can the microsoft documentation regarding validation here:
Microsoft identity platform access tokens
For validation, I can successfully decode using the jwt.ms site for jwt validation. So I know the tokens are good. I can see from the decode the claims and extract the aud(audience) and iss(issuer). These values are not the same for the id token (which I can successfully validate).
I am using the public keys from the following url as documented:
https://login.microsoftonline.com/<TENANT ID>/discovery/keys
So, what I missing in regards to validating the access token? (if I can validate the id token with no issues). How else can i troubleshoot this?
Jim's answer is correct and there are 2 use cases really - so it depends what you are trying to do:
Getting an access token for Microsoft resources - such as Graph - in which case you don't validate them
Getting a token for your own API resources, in which case you need to validate them. For this to work you need to 'expose an API scope' to get a different type of access token
Behaviour is not intuitive in my opinion, since I like to build standards based solutions. If it helps, here is a visual blog post of mine on getting the second scenario above working.
As far as I knew, we do not need to validate Microsoft graph signature. Because MsGraph recognized an opportunity to improve security for users. They achieved this by putting a ‘nonce’ into the jwt header. The JWS is signed with a SHA2 of the nonce, the nonce is replaced before the JWS is serialized. To Validate this token, the nonce will need to be replaced with the SHA2 of the nonce in the header. Now this can change since there is no public contract. So When calling Microsoft Graph, you should treat access tokens as opaque. For more details, please refer here and here
I'm trying to validate access_token retrieved by Microsoft Identity Platform when token request is done (/common/oauth2/v2.0/token), but always I get an invalid format error on any validator even online ones like jwt.io. Do you know why?
My post from a while back may help you to understand the validation process.
A couple of common things to check:
Is there a 'nonce" field in the JWT header? If so it will fail validation and is not designed for your (custom) APIs to validate
Does token validation work if you use the Azure AD v1 endpoints?
I'm making a small React app and want to use Azure to log in. Everyone has an Office 365 account tied to their tenant. I've registered an app in Azure, allowed implicit flow etc., and I can log in via the React front-end. I get the token and can access basic user details via the user.read scope. All good.
I'm using the Msal library to do all of this, and I read somewhere that if I was getting a JWT from Microsoft Graph it would have a nonce in the header and wouldn't be usable for this type of purpose (because Graph could handle validating with each request). I double checked everything and it's calling Msal.UserAgentApplication with my clientId and the login url for our Tenant.
Now, the backend is on AWS, so what I'd like to do is have each request from the user call the API on AWS and include the token in the header.
I've tried validating the token using azure-ad-jwt and even replacing the code with someones suggestions in this post, but I can't get anything but an Invalid Signature.
From what I can see the code in the those links basically decoded the JWT, tracks down the public keys from Microsoft, find the matching one based on the kid, does some tidying up of the cert, and tries to verify it. But it constantly returns:
{
"name":"JsonWebTokenError",
"message":"invalid signature"
}
The backend is written in Nodejs, I can't think of any more reasons why it won't work. Anyone get this working or have any ideas?
For what it's worth, I've also pasted the token into jwt.io and it decodes find, but also says Invalid Signature, though up to this point I've assumed that is because I haven't put in the public key or cert.
I'm using developer sandbox to make all my api calls.
It's website build with laravel 5.2
All api calls are made with guzzle/guzzle.
I'm trying automate sending pdf contracts (creating envelopes) using docusign api.
I followed steps from Using the Authorization Code Grant
I had no problem with:
Starting the Authentication Code Grant
Handling the Response
Exchanging the Code for a Token
Getting the User’s Account and Base URI Information
After I get userinfo, there is only one account, so I used that accounts base_uri for all subsequent api calls
{base_uri} + "/restapi/v2/accounts/" + {account_id}
In all my subsequent api calls I'm also adding header
Authorization: Bearer eyJ0eX...MrhIddzBAQ
where I'm using access_token that I've got in step Exchanging the Code for a Token
When doing a create envelope api call, or any other api call, using access_token, base_uri and account_id I get
POST https://demo.docusign.net/restapi/v2/accounts/<account_id>/envelopes resulted in a 401 Unauthorized response
What I tried
Test using the access_token in docusign API explorer:
I went to API EXPLORER - create envelope
I used Authenticate using Sandbox Account to authenticate with the access_token that I've got in previous calls to docusign. Same for the account_id.
When I click on SEND REQUEST, I get 401 Unauthorized response again.
When I use Authenticate using Sandbox Account, but this time I click on Get OAuth2 token (that generates new token), and I click on SEND REQUEST, I get success message.
Then I copied this access_token (from Request) into my website to test the api call, and this time it worked. It also worked for all other api calls that I was making to docusign.
So, using access_token that I get after Exchanging the Code for a Token, I get 401 Unauthorized for api calls
When I use access_token that I generated in API explorer, all api calls to docusign work in my website.
What I also tried
Use refresh_token to get new access_token. Still 401
Xdebug, going step by step to make sure that all params/headers are set before api call. They are, and they are the same as api explorer.
Guzzle option debug => true to get more information about the request, and to compare with what's sent in API EXPLORER, and they are basically the same, except the tokens.
Postman to make request to api, (just to eliminate any chance that I have errors in my code), with same behavior:
401 with token that I get from docusign
success when using API EXPLORER generated token
I'm kinda lost on what to do next and how to solve this, I'm sure it's something simple, but I can't seem to locate the problem.
Update
I used Larry K's answer and found that my problem was with the scope value in /oauth/auth call. I changed it to scope=signature%20extended, and everything works perfectly!
When you click the Get OAuth2 token in the API explorer, you are going through the complete Authorization Code Grant flow, including the new token.
Since this works, but the token your app obtained via the OAuth Authorization Code flow doesn't work, this tells me that your app has an issue.
Check:
Logout from DocuSign. Login from your app. Are you transferred to DocuSign to log in correctly? And then redirected to your app?
Are you requesting the "signature" scope in your request? Check spelling and capitalization of the scope name!
When you're redirected to your app, your app receives the authorization code as a query parameter. Do you get it ok?
When you convert your authorization code to a bearer token are you storing the complete bearer token? It is quite long.
When you send your Envelopes::create request, are you including a space between the word Bearer and the token itself?
Are you making your API call to demo.docusign.net (not .com)
If the above doesn't help, then please update your question (you can edit your question itself) with a trace of your request.