How to obtain the docusign user guid to set on the JWT sub attribute? - docusignapi

It seems that I am missing a piece in the JWT Consent Flow.
I craft the following consent url and link it to a button that will
open a popup for the current user to login and accept the consent:
https://account-d.docusign.com/oauth/auth?response_type=code&scope=signature%20impersonation&client_id=#{my_integration_key}&redirect_uri=#{redirect_url}"
Once redirected, the documentation specifies that I should simply
ignore the code param in the redirect url.
I must create a JWT token in order to obtain an access token : At
this point I must specify the 'sub' with the user ID of the user who
just granted consent. How I am suppose to get it in this flow? I
don't understand why I should ignore the code param in the oauth
redirect, I should use it to find the DocuSign user guid.
Am I missing something ?

The userId GUID can be obtained in many ways, but that depends on the flow of your app.
You could go to check it in the Settings (admin) portion of the web app, either in the "Apps and Keys" page, where you get the logged in user ID, or in the
"User" where you can find any and all users in the account.
However, if you want to do that programmatically, you are in a catch22, as to make an API call to obtain this information you need to first be authenticated. Typically, this can be done by hardcoding a primary user (system user) that was set manually and that user then make API call to obtain all other users and their GUID (userID) respectively.

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).

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.

DocuSign JWT Grant how to get GUID userId of the user to impersonate?

I am doing service integration with DocuSign platform using JWT Grant auth type. DocuSign account has multiple users setup.
My service is SendEnvelopService and one of the important request param to the service is user email. SendEnvelopService need to impersonate user with given email-id when calling DocuSign and send envelope in behalf of that user. Note that every request to SendEnvelopService will have different value of email request param.
I have following questions around it -
Question#1) Since I need to impersonate different user every time (based on email id in my request), I assume I need to get new JWT auth token every time, before making actual api call. Is that right? Is it usual and ok to request new JWT auth token so frequently before every api call? Does it raise any integration concerns with DocuSign?
Question#2) In my request, I have email id of the user to impersonate. I don't have user's GUID which I need, to get JWT auth token and impersonate it. Is there any api that I can use to get user GUID by email id? I wonder what kind of authentication will be needed for such api because I don't have JWT auth token yet.
One idea I have is may be I need to setup one admin user in DocuSign and keep admin userId (GUID) in application config. Now I have 2 users, one is admin user and another is request user which I have email from the service request. I can following steps -
Do requestJWTUserToken impersonating admin user. We get
oAuthTokenAdmin
Using oAuthTokenAdmin make
https://developers.docusign.com/esign-rest-api/reference/Users/Users/list
api call to get userId (GUID) of request user email.
Now do another requestJWTUserToken impersonating request userId. We
get oAuthTokenUser
Now make actual api call using oAuthTokenUser and to send envelope
Go to:
https://admindemo.docusign.com/
Log in with your demo (sandbox) credentials.
Then you have two options:
If it is only for you, simple thing is to click "API and Keys" page under Integrations on the left nav.
You will see this:
You can also click on "Users" on the left and select the user you want, any user really, doesn't have to be you.
then you'll see it under this:
For your first question, no, you don't have to do that. You can use the same user for all API calls. Especially if this user is an admin, then you can do all API calls under that context.

Azure B2C (IEF/Custom Policy) - State parameter

I have the following flow for sign in / sign up, when using sign-up:
Present user with sign up screen, allow them to enter email/password/name
Validate input, then send email (rest api) and set verification attributes in b2c custom extension properties
User then receives email with verification link
User clicks link from email and gets sent to a new user journey for the return trip
New user journey gets parameters from the querystring (email + verif code)
B2C validates the verif code + expiry
IF user is verified, they're set as verified via custom extension attributes, then sent to the (ASP.NET MVC) application.
Here's where I'm stuck - B2C is sending the jwt token back to the app, but the user doesn't get 'signed-in'.
Am I missing something at step 7? I don't have the "state" variable in my querystring, am I expected to build and include it somehow so that B2C and the app can communicate? I'm lost at this point. I'd post some of the b2c policy xml but not sure what would even help...
EDIT: reply to Jas:
Is that the only way (make an app call b2c for an auth request)? We have multiple apps that a user can use to sign up through b2c, so I was hoping to avoid having to make changes to each of them. Instead I was hoping that B2C could tell the app after account verification that "this user is ok".
I did previous look at https://github.com/azure-ad-b2c/samples/tree/master/policies/sign-in-with-magic-link (written by you!), but again, was hoping I could avoid having to do that work inside of each of our apps.
Here's an example of the jwt 'id_token' I'm trying to pass to the app:
id_token
Side note: Is 'id_token' the same as 'id_token_hint'? I couldn't find whether they're the same or different when googling it.
What you need to do is send the invite link in the email as a link to the app, eg https://myapp.com?id_token_hint=value.
Then have your apps account controller make an auth request to the policy to complete the account redemption along with an extra query parameter “id_token_hint=value”. Now a proper auth can happen with your applications openId middleware initialised.

Authentication using Facebook with Passportjs: what is accessToken for, what should I store after registration?

I am using Passport to register/authenticate using Facebook.
When oAuth is successful, I am returned:
accessToken
refreshToken
profile
Now... when a user successfully registers using Facebook, I store accessToken and the profile info.
When somebody wants to login, and goes through the oauth motions again, my app once more gets accessToken and profile.
Trouble is, accessToken is different. I actually expected the accessToken to be the same after the first authentication...
At this point, I am connecting my own local user with the facebook's id field from the profile. But... how would I actually use accessToken? Does it even make sense to keep it? If so, why would I actually keep it?
I actually expect accessToken to be the same, and use that to match a successful login. I obviously can't do that... so I am confused!
You need to keep accessToken if you want to query facebook's API on behalf of your logged-in-via-facebook user. If you want to use facebook just for login only, you can discard it. If you want to ask facebook for the user's most recent status update, for example, you need to include that accessToken as a parameter when making that API call. The point of the accessToken is that it allows a set of operations on behalf of a user, but it expires so if it falls into the wrong hands it cannot be used to cause as much damage as a permanent token or the user's actual password. It will be different every time by design.
You should store facebook Id. It should be in the profile object. Access token will change according to facebooks policy of authorization. What you should be doing is
Get the user to login through facebook
Check their facebook id against the facebook id in your database.
Access tokens expire frequently as described here

Resources