Many users in account and app integration - docusignapi

When performing authorization code grant authentication, Docusign asks for consent. Far as I understand documentation, it's user's consent implied. When first asked for consent, the user is required to enter his credentials. When asked next time, the same user is implied.
However consider this: I have 3 users listed in my demo account wowproj.dev#gmail.com: the wowproj.dev#gmail.com himself, and Mary#inbox.ru, and Mike#inbox.ru.
I need to know two things:
1) whether I can statically specify the user when doing code authorization (say, by his "api username"), so that the user only has to press some "OK" button (maybe enter his password as well, but not username) - is that possible? Otherwise it may be possible that I have users "Mike" and "Mary" in my app, and I have those users in my Docusign account as well; then "Mike" user of my application starts some action, but when asked for consent, "Mary" enters her Docusign credentials and gives her consent. I want the consent to be Mike's! For example, I could store Mike's api username in his account in my app, and use it in grant authorization. But, far as I can see, neither user's login nor his api username are sent to Docusign in authorization code request, so I don't see how to achieve what I want.
2) When asked next time, the same user is implied - that may be a problem. What if my "Mike" from former paragraph, when asked by Docusign, enters his credentials and gives his consent, then he logs out from MY application and Mary logs in instead and starts some action involving Docusign; will Docusign assume it's still Mike's session? How do I make sure this does not happen?

I don't understand your question's use of "implied." Here's how it works. If you have further questions, please update (edit) your original question.
When using authorization code grant, the user first authenticates himself to DocuSign.
Then, if he hasn't previously done so, he is asked to grant consent to the integration. The permissions requested by the integration are the integration's scopes. The usual scope is signature, there can be others.
After he grants consent, the DocuSign authorization service will redirect the user's browser back to the integration, and and an authorization code will be included as a query parameter.
Your integration then makes an oauth call to DocuSign to exchange the authorization code for an access token.
Next (typically), your integration uses the OAuth::getUserInfo method to obtain the user's name, email, authorized DocuSign accounts, and more from DocuSign.
Ensuring that your app's user is the DocuSign user
You can't force who will be authenticating with DocuSign. But you can check that the right person authenticated. For example:
Mike logs into your app. You know Mike's email.
Your app wants its user to authenticate with DocuSign. Your app initiates the OAuth Authorization Code Grant flow with DocuSign.
Your app's user now sees the DocuSign login screen.
(The problem) is that Mike asks Mary to authenticate with DocuSign for him. Mary does so.
But when your app learns the email address of the DocuSign authenticated user, it will be Mary's email address, not Mike's. So your app can reject the DocuSign authentication by posting a message to the user saying that Mike must re-authenticate with DocuSign.
By implementing the above, your app can guarantee that when Mike is logged into your app, the matching authentication with DocuSign will be Mike's DocuSign user account, never someone else's.
Instead of comparing email addresses, you can also use the DocuSign user id. But doing so requires that you go through a step of loading your app with a table that associates Mike's account and his DocuSign User ID. Email addresses are probably easier.
Re: other people logging in after a prior session
There are two cases:
Same browser on the same machine
This is the "public computer problem."
Mike uses browser "G" to login into your app and also into DocuSign. Later Mary slides into his seat and uses the same browser and same application.
By default, DocuSign's OAuth Auth Code Grant enables Silent Authentication. This means that the DocuSign auth flow will silently enable Mary to use Mike's DocuSign session (if it is still active). For a public machine scenario, this is obviously not good. Solutions:
Always require DocuSign to actively authenticate the person (no Silent Authentication allowed). To do so, include prompt=login in the initial URL sent to DocuSign. See docs.
Clear the browser's cookies between users. The standard methods for handling public computers will include this.
Different users on the same app
Your app should use sessions. Each user of the app (in parallel or sequentially) will get their own session. Each session should maintain its own authentication information for DocuSign including the current user's access token, account id, and base url.
All of that information is determined as part of the authentication-with-DocuSign process.
These days, all modern web app frameworks provide easy to use session interfaces.
We also have code examples you can use. See this repository list. (With more on the way.)

Related

What are the best practises using Docusign's 0Auth API?

I'm using authentication code mechanism through Docusign's API for integration and works as expected.
Have a question regarding the documentation about implementation best practises, described in this page
Questions are related to the diagram at the end:
Question1
In Get the user's account ID, base URL and name (1st square) how do you recommend fetching the user/account information as before consent we don't know who is giving consent?
If it is related to users that may have given consent before, is it even necessary? If tokens already exist for the user, what is the purpose of verifying this scenario?
In the documentation it seems this is reinforced further with what is stated next:
How will we know what is the account/user information before the user gives consent?
Question2 (Similar to above)
In Collect the account ID (GUID) and name of the user, when no access token is found, I'm assuming we should redirect the user immediately so that the use gives consent again. Similar to the question above, in the diagram it indicates we should do this action "Collect account/user info" somehow before redirect for consent? We only know it afterwards as well, so is it needed?
It would be great if it would be possible to clarify the above!
As Inbar commented, that diagram needs some work. I'm sorry for the confusion.
Here's my recommendations for user present (Authorization Code and Implicit grant flows) and user absent (JWT grant flow).
All authorization flows
Determine if your users will typically use your application with a particular eSignature account or with any of their accounts. (It is common for customers to have access to more than one DocuSign eSignature account.)
If a particular account will be used, then provide an installation screen for your app where the admin can enter the account ID (use the guid format).
Your installation screen should also enable the installer to set
the DocuSign OAuth service provider, either production account.docusign.com or demo account-d.docusign.com
User present: Authorization Code and Implicit grant flows
Your app may or may not have its own login sequence for users. Your app needs a DocuSign access token for making API calls to DocuSign APIs.
When your user wants to authenticate with DocuSign:
Start the Authorization Code or Implicit grant flow.
When the flow is done, your app has an access token.
If the Authorization Code grant flow was used then you also have a refresh token.
Use the oauth/userinfo API call to obtain information about the user:
Their name and email
The eSignature accounts they have access too, and which of those accounts is the user's default account
For each account, the name of the account and the baseUrl for making API calls to the account.
If your app's users use a preferred account, then check that the user has access to the preferred account. Else, note the account id of the user's default account. (Also be prepared to handle the cases where there is either no userinfo response, no account or no default account for the user. These are infrequent DocuSign errors and can be fixed by contacting DocuSign Customer Support and referencing this article.
Use the expires_in OAuth response attribute to calculate your expires datetime. Then subtract 10 minutes so you have a buffer between the time you'll last use the access token and when it actually expires. You now have the last_use time.
Store the user's information, including the account id, base url for the account, access token, and last_use datetime.
If you have a refresh token, store it (and the user's information) in non-volatile storage.
When your application wants to make an API call
If you have a current access token for the user (last_use datetime is after the current datetime) then use it.
If the last_use time has passed, then use the refresh token if you have it. When refreshing the toke, you'll receive a new refresh token. Store it in non-volatile storage, overwriting the prior refresh token.
If no refresh token, then your app will need to ask the user to authenticate again.
Do not use oauth/userinfo again after either the token was refreshed or the user authenticated again. Keep and use the userinfo obtained after the person first logged in.
When your user wants to use a different account
Provide a "Switch accounts" feature to enable users to choose which of their accounts should be used. (Only applies if any account can be used with the application.)
User not-present: JWT grant
Your app's configuration screen will also need the user id in guid form. You can either store these values or look them up from DocuSign.
Decide whether a specific account is needed or not (see above).
Decide how the user will grant consent. See this video for more info.
First time your app needs an access token after a reboot
Use the JWT user grant to obtain an access token
As above, calculate the last_use datetime including a 10 minute buffer.
Use oauth/userinfo as above to determine if the user has access
the account or what the user's default account is. Also obtain the account's base_url.
Store the information.
Use the access token to make the API call.
Subsequent API calls
Check the last_use datetime. If it hasn't yet occurred then use the stored access token. If it has occured, then redo the JWT user grant flow but do not make another oauth/userinfo call--use the prior information.
Question 1 - You do not need to remember which user gave consent. That is not something you should do anyway, because users can revoke consent and then your information will be inaccurate. The system will ask for consent if needed (and if you ask for additional scopes it may be needed even if consent was given for example).
Question 2 - You should redirect immediately, whether consent is needed or not is unclear, but the user will either have to login, or just redirected if they have a cookie and consent is also based on their circumstances.
I'll consent (no pun intended) that we can improve this diagram and make it easier to understand. I would suggest implementing a simple scenario first and seeing how it work before moving on to the more advanced scenario (by simple I mean every time a user need to log in as if it was their first time).

JWT or AWT for DocuSign integration

I am building an application that will be used by end users in multiple organizations to create and send envelopes for signatures. I am trying to figure out the correct authorization workflow. For this example, say I am manish#example.com.
My understanding of JWT is that JWT will impersonate manish#example.com when any of these 1000's of end users in different organizations send envelopes. Is that correct? But if so, won't they need to authorize the app to impersonate me when they first try to create an envelope? How will these users get my credentials? Would I have to share my credentials with all these end users of my application? Can they log in with their own credentials instead? But if my application is impersonating my own credentials to send envelopes on behalf of these end users, why do I need permission from these users to use my own credentials? After all, in the JWT workflow, the redirect URL does not return any information about the identity of these users of my application.
So, if my app impersonates me, how do end users get my credentials? And, if my app impersonates me, why can't I give this permission to the app once and for all at the time of creating the app? Why do end users have to permit me to impersonate myself?
On a related note, JWT is working great when I use my own personal DocuSign API credentials to authorize my app in testing. But when I try to use my own organization credentials to authorize the app, I get the following error. I also get this error when I try the AWT workflow. How can I fix this error:
Sorry, but we’re having trouble signing you in.
AADSTS50105: The signed in user 'manish#test.edu' is not assigned to a role for the application '225d2ddd-e3a3-4bed-a310-8a9b8786363e'(Docusign Test).
Help in setting up the correct authorization workflow would be great.
JWT enables developers to request a token on behalf of some user without that user having to log in.
That means that except for the first time when the user have to consent - there's no web UI required to obtain a token.
JWT tokens are for a specific user in a specific account and it's the GUID of that userID that is used to uniquely identify a user. If you have multiple accounts - you will have to ensure you use the right userID for the right user for the right account.
Note also that users in DocuSign have different permissions profiles and may or may not have the access required to do what the API is trying to do.
Finally, clarifying one last thing, you wrote :
when any of these 1000's of end users in different organizations send
If you have thousands of end users that will be sending envelope (not just signing them) then JWT is probably not the best choice for you. You can still use it, but you will need some way to know the userId of the user which means you'll need some uber-auth JWT user that is used first or keep tables of users (I assume users can be added/removed etc.) it's not an ideal way to do things.

DocuSign: How to get an authorization code programatically

I have a vuejs SPA. Users have their own accounts with a dashboard. On the dashboard, is a section for PDF signing. All users should have the same PDF displayed, but with their name pre-filled on the PDF, and then 4 spots to sign.
Right now I am stuck on the first part for using the API....which is the auth code.
Why does it seem that the tutorial I followed, requires the owner of the DocuSign account to login and grant rights? I had to do something similar to https://account-d.docusign.com/oauth/auth?response_type=code&scope=signature&client_id=5665656-3506-46fa-b46d-f6acf3b59268&redirect_uri=https://www.google.com and I got a code in return....but how am I even suppose to implement this for my web app?
How do I get the auth code in the background....meaning...I cant have all users go to this URL...am I supposed to do it via ajax GET? I was able to use a correctly formatted URL, but I got the response by visiting the URL in my browser...how can I do this programmatically?
I dont get the granting rights part....because there is no way this would be practical where all the users would have to know my private DocuSign account info?
Of the (3) oauth methods, which is best for my scenario? Authorization Code Grant, Implicit Grant, or JWT Grant
Auth Code Grant was meant for interactive scenarios. It requires UI and a web interface. It cannot be used without UI. Once you have the initial access token, there's a refresh token to be able to obtain a new one without UI, but the initial call requires UI.
The users don't have to know your account info, your account info may not be relevant. The user grant a right to your app/integration to make API calls. That is not your account, it is different. It's a clientId/integration key that you use your account to create, but it can be used with any DocuSign user/account.
JWT would allow for what you asked in #1 but only after a one-time consent was provided (What you asked in #2) by the end-user. You have to do that for users to enable DocuSign to make API calls on their behalf.
Final word, signers do not need an account in DocuSign. I don't know what you're building, but if your end-user just signs - they don't need an account and a lot of 1-3 is moot.

Docusign - How do I skip Obtaining Consent

I searched through previous questions but I haven't found a clear answer. My work flow is as follows:
I have a front end web app that talks to a node back end.
The node backend create a PDF and we would like for the user to sign it.
We use Authorization Code Grant
The user is redirected to the Obtain Consent screen
Once consent is granted they are redirected back to our app with a code that is swapped for an access token
We then use that access token to create our envelope and redirect our user to docusign for signing.
I would like to REMOVE the NEED for the user to provide consent. I have seen other companies leverage docusign without needing it.
My questions are:
- Is Authorization Code Grant the right authentication approach or should I be using JWT Grant?
- How can I get an access token for the user without obtaining consent? This seems like a necessary step?
- If I switch to the "Organizational Admin" approach, does my work flow change where I no longer re-direct the user to obtain consent? IF this is the case, how do I get an access token?
The users who are signing the document are not part of our company and do not share the same 'company email domain'.
I'd really welcome all feedback on this. Thank you.
If you just need users to sign, they do not need to log in to DocuSign at all. They don't even need to have a DocuSign account to sign.
Consent is only needed once per user/app. It cannot be avoided, as the user must agree to the app doing things for them.
If you use JWT - there's no need to login except once.
Hope this helps.

Need clarification of Invitation flow in WingTipGames

I'm building an API to support user provisioning for other application teams around my company. I have a decent understanding of custom policies and have reviewed the invitation flow in WingTipGames, however the sample app is at times hard to follow given the sheer amount of functionality it offers. I would appreciate some clarification around what features I can ignore, vs what is required to support my use case.
Use Case:
My API's CreateUser method creates the user in B2C with ADGraph, then should generate an invitation link that includes a signed JWT with the user's email address, and finally email the link to the recipient. The new user will click the link, which should redirect them directly to the Invitation policy to reset their password.
Clarification Needed:
I'm struggling with simple generation of the Invitation link. What's shown in the sample seems overly complex for my API. In general I'm confused about the OIDC setup given that my API itself (while separately requiring callers to authenticate) will not be involved at all when the recipient clicks the invite link. And as this is an API not an MVC app, I wonder if the process can be stripped down vs the invitation flow in WingTipGames.
Why is ChallengeAsync called in the Invitation\Create method? Presumably this is why we then land in the OnRedirectToIdentityProvider event. Is the challenge what is somehow intercepted and translated into the invitation link?
Are the classes in WingTipCommon relevant here? Namely the AspnetCore.Authentication.OpenIdConnect extensions, handler, and middleware. Asking because users should never arrive at the API in response to clicking the invite link so perhaps the extra plumbing is unnecessary.
Users will always be in a new browser and session when the click the redeem the invitation link, and will redirect directly to the policy (if I understand correctly). Do I still need to worry about the skipCorrelation and XSRF handling?
Any other general suggestions around what to pull out of the sample and what to ignore to support my use case are appreciated.
Thanks
Mark
The Wingtip Games application implements the following flows for invitations:
An invitation link to an application endpoint. This invitation link contains the e-mail address of the invited user, an invitation expiration, and a HMAC-based signature. When the invitation link is opened, the application endpoint validates the HMAC-based signature and the invitation expiration and, if they are valid, then it redirects the invited user to the policy endpoint. This policy redirection contains a signed JWT with the email address of the invited user.
An invitation link to the policy endpoint. This invitation links contains a signed JWT with the email address of the invited user.
I prefer and recommend the first flow for invitations because the application endpoint can implement the invitation logic before the invitation policy is run (e.g. the application endpoint can validate the invitation expiration and, if it isn't valid, then it can display an error message) as well as after the invitation policy has run (e.g. the application endpoint can display a success message).
To answer your specific questions:
Why is ChallengeAsync called in the Invitation\Create method?
This is called for the second flow for invitations. It is called so that the authentication middleware can generate the invitation link and send the invitation message. It is implemented like this so that the application logic doesn't have to be aware of the application identifier, the policy identifier, or the redirection URIs that are required for the invitation link.
Are the classes in WingTipCommon relevant here?
They are used to support the second flow for invitations. See the next answer.
Do I still need to worry about the skipCorrelation and XSRF handling?
This is implemented for the second flow for invitations. As result of the invitation policy, Azure AD B2C issues an authentication response to the client application, where this authentication response is processed by the authentication middleware. Because the authentication middleware doesn't invoke the invitation policy (i.e. it is invoked by the invitation link), then the authentication middleware must be configured to disable the built-in checks for correlation of an authentication request with an authentication response.

Resources