I need to add DocuSign to my chat app (iOS, Android, Windows) in order to ask to sign documents to all the chat group members.
I want to implement DocuSign signing flow without Server implementation: only Sender and Recipients client side implementation (is it possible?).
Flow that I imagined:
An authenticated Sender create the envelope with Envelopes: create REST call.
Other members must sign the document (no DocuSign account needed)...
...so I need to generate a "recipient url" for every member using the REST call EnvelopeViews: createRecipient (who call this endpoint?)
I tested this flow with Postman and I've some questions:
EnvelopeViews: createRecipient require X-DocuSign-Authentication header, so this request must be called from Sender side, is it?
EnvelopeViews: createRecipient return an url that can be used once, why? The second time I use this url I get 404 as response.
So what I notice is the Recipient can't use the url (provided by the Sender) twice but he can't generate a new url every time because it isn't authenticated (no X-DocuSign-Authentication).
How can I implement this flow properly?
Lots of good questions:
EnvelopeViews: createRecipient require X-DocuSign-Authentication header, so this request must be called from Sender side, is it?
Do not use the X-DocuSign-Authentication header. That's "legacy authentication" and DocuSign does not support it for new REST eSignature apps. Instead, use OAuth. Probably the OAuth JWT grant flow since that flow enables your application to impersonate a DocuSign user (such as the sender), when the user is not present.
You can call EnvelopeViews: createRecipient from your server or from your browser app. If you call from your browser then you'll need to implement a private CORS gateway.
Either way, when the signer is ready to sign, you obtain the signing ceremony URL from the EnvelopeViews: createRecipient API call, then redirect the signer's browser to the URL.
EnvelopeViews: createRecipient return an url that can be used once, why?
For security reasons. That's part of our information security architecture. And not only is the signing ceremony URL only usable once, it is also time limited. It should be used within a minute or two from when you receive it from DocuSign. It will expire 5 minutes after it was created.
The second time I use this url I get 404 as response.
Yes, that's as designed. You get the URL, then you immediately redirect the signer to the URL. Then they sign. Then they're redirected back to your application.
If you want to provide a URL to a signer that the signer can use later on, you can implement that flow yourself. I've described how in other answers.
So what I notice is the Recipient can't use the url (provided by the Sender) twice but he can't generate a new url every time because it isn't authenticated (no X-DocuSign-Authentication).
How can I implement this flow properly?
You're almost there. Implement the JWT grant flow in your application. That way your app can impersonate the sender even when they're not around. When the signer wants to sign, your app gets the signing ceremony URL from DocuSign, and then redirects to enable signing.
An alternative which also works fine is for the sender to sign in to DocuSign by using the standard OAuth Authorization Code grant. This provides your app with an access token and a refresh token.
Your app enables the sender to send the enveloper by using the access token.
Later, when the signer wants to sign, your app uses the refresh token that it stored to generate a new access token. Use the access token with the EnvelopeViews: createRecipient API method to obtain the signing ceremony URL.
X-DocuSign-Authentication header is legacy authentication, please don't use this as it's not as secure as modern OAauth.
Again, security. Every time you want someone to sign your code should generate the URL. Also, note you cannot generate two URLs. Only one is valid at a time. You need your app to have some logic to ensure that only one user is signing and only at that point in time the URL is generated.
Related
I'm writing a Python/Django integration with DocuSign, where users will be sent from another application to DocuSign to sign a document, and then be sent back to the initial application. These users do not have DocuSign accounts.
I am currently using "request_jwt_user_token" alongside our service account generate the an envelope, attach a document, and create a recipient view. At the end this returns us a url like:
https://demo.docusign.net/Signing/MTRedeem/v1/[random_string]?slt=[random_long_string]
I'm pretty sure the first random string is an identifier and the latter is an access token?
What I'm trying to understand is how secure this info is to pass on to arbitrary users. I'm keeping the jwt expiration low and setting the jwt scope to ["signature", "impersonation"]. But can the slt token be used to access other envelopes or do other signature api calls? I assume it can't be used for anything outside of signing due to the scope.
The URL you posted here has nothing to do with JWT. It's an embedded signing URL that you can redirect your user in order to complete signing. They can then be redirected back to your app after they're done.
This URL expires in 5 minutes (or 2 minutes) and so it's very secure. It is also a URL that can be used only by one user (the one you set as the user signing the envelope and generated with the clientUserId)
The access token can be used to access other envelopes etc, but that access token is NOT in this URL and should never be shared etc.
I am trying to create a embeded sign in url from backend webservice and open that url in the mobile application for signing.
For that in backend first of all i need to get Auth token.
To fetch auth token i need to get Auth code. For this i need to build a url with redirect url and when i open this url it will be redirected to given redirect url with auth code.
https://account-d.docusign.com/oauth/auth?
response_type=code
&scope=YOUR_REQUESTED_SCOPES
&client_id=YOUR_INTEGRATION_KEY
&state=YOUR_CUSTOM_STATE
&redirect_uri=YOUR_REDIRECT_URI
&login_hint=YOUR_LOGIN_HINT
But this process is manual and auth code from this is valid for 2 minutes only. So each time i have to build url and get auth code.
Is there any automated programmatical way to fetch auth code or generate auth code which will not expire.
If the signer is also the DocuSign account user, then Authorization Code Grant is the right way to go.
It sounds like you're not implementing authorization code grant correctly:
You redirect the user's browser to the DocuSign OAuth service (account.docusign.com for production, account-d.docusign.com for development).
After the user finishes authenticating with DocuSign, the authentication service will redirect the user's browser to your redirect_uri, which you supplied earlier.
Your application, initiated via the redirect_uri then exchanges the authorization code for an access token. There's nothing "manual" about this process other than manually entering the email/password for authentication.
JWT Grant when the DocuSign account user is not present
It could also be that the signer does not have an account on the DocuSign system. (This is the more common situation.) Signers do not need DocuSign accounts, only senders do.
In this case, your application should use the JWT Grant flow to impersonate a DocuSign account user--either a real person or a "system account" such as "Payroll Department."
The JWT Grant flow is used to obtain an access token. Then your server-side software would use the API to send the envelope, and then to obtain an embedded signing ceremony URL. Next, redirect the user's browser (on the phone) to the signing ceremony URL. After the signer signs, the DocuSign signing ceremony software will redirect the user's browser back to your application.
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.
I need to use docusign in the app to let the user sign the contract, but I found that the REST api using docusign requires authorization, and the authorization requires the user to log in to their docusign account.
Is there another way for users to authorize and sign without logging in?
Yes, to send an envelope (transaction), an access token is needed. But not for signing. There are several workflows available to you and your app:
Use a Powerform. In this use case, a DocuSign user creates the template for the envelope and turns it into a powerform. Now, anyone with the url (including your Android app) can cause an envelope to be created automatically and then start the signing process. No access token needed by the signer!
Use a server-side process to create the envelope, including any customization needed. Since the server process is operating on its own, it'd use JWT authentication to obtain an access token for creating the envelope. It'd also create the signing ceremony url from DocuSign. Your Android app would then open the signing ceremony url to let the app user sign the document(s). No access token is needed by the Android app.
Your Android app could obtain a DocuSign access token from its server. Then your Android app could directly use the DocuSign API to create an embedded signing url for the app user to use. The access token would represent the app, not the person signing on your app.
Code examples
JWT authentication code examples
Embedded signing examples: see example eg001 source from any of the repos.
We are looking at the DocuSign API integration using .NET.
I've managed to send an email from this correctly and added fields to the form programmatically however I could do with knowing how to use the Send On Behalf feature.
It looks like in the APILogin() function I need to add a default header called X-DocuSign-Act-As-User and then the email address (SOB is enabled on the API account). But then it says I need something to do with a token for this user? But not sure where I get this from?
Thanks,
Alex
X-DocuSign-Act-As-User header is only applicable when using OAuth tokens. For non-token usage, add the X-DocuSign-Authentication header.
Example from the GUIDE:
X-DocuSign-Authentication:<DocuSignCredentials><SendOnBehalfOf>bob.smith#gmail.com</SendOnBehalfOf><Username>{name}</Username><Password>{password}</Password><IntegratorKey>{integrator_key}</IntegratorKey></DocuSignCredentials>
Where {name} is the email address of your API Initiator and {password} is the password of your API Initiator. Those credentials are used to authenticate the API call, but the envelope will be created and owned by "bob.smith#gmail.com" as the Sender.
Note 1: "bob.smith#gmail.com", i.e. the on-behalf user, must be an account member with "send envelopes" permissions.
Note 2: API Initiator credentials - recommendation is to use API Name (the User's GUID) rather than email address, and use the "encrypted password" instead of the plain-text password. This is retrievable via the login_information API call. These forms of the credentials are not useful for logging into DocuSign via the Web interface.