Getting a DocuSign access token for an SSO user - docusignapi

I'm trying to get access tokens for users in order to use the iOS SDK for integrating in-person signings.
Our DocuSign users are set up as Single sign-on. We have a non-SSO, API user configured with the user settings apiAccountWideAccess and allowSendOnBehalfOf enabled.
I request an access token for the non-SSO, API user as follows:
POST /restapi/v2/oauth2/token HTTP/1.1
Host: demo.docusign.net
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
grant_type=password&client_id=<client_id>&scope=api&username=<useranme>&password=<password>
This results in the following response:
{
"access_token": "<access-token>",
"token_type": "bearer",
"scope": "api"
}
I then use the access token from the above response to try to get an access token for an SSO user as follows:
POST /restapi/v2/oauth2/token HTTP/1.1
Host: demo.docusign.net
Authorization: Bearer <access-token-from-response-above>
Accept: application/json
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
grant_type=password&client_id=<client_id>&username=<email-address-of-sso-user>&password=&scope=api
This results in the following response:
{
"errorCode": "UNSPECIFIED_ERROR",
"message": "Object reference not set to an instance of an object."
}
I'm following the documentation here (Obtaining access_tokens for Other Account Users).
Is it possible to get access tokens for the REST API on behalf of SSO users?

Unfortunately you can not use the API as a SSO enabled user at this time.
If you need to use the API as a SSO user, you have to have that user on the SSO Exempt list.
Generally integrations use Send On Behalf Of to authenticate as the API user (that on the exempt list) and makes the calls on behalf of the users who have SSO enabled.
The error doesn't indicate the actual issue and I've filed a bug with DocuSign Support to get that portion addressed.

Related

Not getting refresh token and id_token with Azure AD OAuth2.0 ROPC flow using username and password

I am using ROPC Flow with user details and client details to get Access token and refresh token. But I am only getting Access Token and this expires in 1 hour.
My frontend app has sign-in window where we provide AD user creds, this makes a post request and got FE with successful auth.
I have 2 questions:
Getting CORS issue while making user sign-in request using http://localhost:3000 with access-control-allow-origin header error.
I would like to get refresh token for Continues App login OR do I set the lifetime of the access token to a day.
REQUEST:
// Line breaks and spaces are for legibility only. This is a public client, so no secret is required.
POST {tenant}/oauth2/v2.0/token
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&scope=user.read%20openid%20profile%20offline_access
&username=MyUsername#myTenant.com
&password=SuperS3cret
&grant_type=password
RESPONSE:
{
"token_type": "Bearer",
"scope": "api://94849942785375897059789375379/FIles.Read",
"expires_in": 3598,
"ext_expires_in": 3598,
"access_token": 8YU4bMhafsfhaeoahehviyy8786w89ufo2ofj29h8gMWnB633NLWn7JQ"
}
You need to add offline_access and openid to the scope parameter when requesting the token, try to add them, you will get the id token and refresh token.
Update:
Your application will need a back-end that will fetch the data and return it to the front-end. So try to call the token endpoint from the back-end .

Calling Azure WebApi from Postman with specific scope

I use Postman to test my API hosted in Azure. First I get an Access Token like this
Since I use the grant_type ´client_credentialsI have to use the default scope like this api://my-app-id/.default` as explained here.
But one of the endpoint of my API requires a specific scope, so the call fails because my access token does not contain this scope.
How am I supposed to test from Postman with the required scope ?
If you use Client Credential Flow to obtain an access token for an api protected by Azure, you must create an application and grant application permissions to the application (this is because Client Credential flow has no user interaction).
Then you need to define the application permissions by editing the list of api applications.here is an example.
Next, grant application permissions to the application:
Refer to this document and use Client Credential flow to get access token here:
1.First you need to get the administrator's consent:
GET https://login.microsoftonline.com/{tenant}/adminconsent?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&state=12345
&redirect_uri=http://localhost/myapp/permissions
2.Then you can get the access token by sharing the secret:
POST /{tenant}/oauth2/v2.0/token HTTP/1.1 //Line breaks for clarity
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=535fb089-9ff3-47b6-9bfb-4f1264799865
&scope=api://your-app-id/.default
&client_secret=qWgdYAmab0YSkuL1qKv5bPX
&grant_type=client_credentials
Parse the token and you will see your custom roles:
Try using the token to access your API.
Update:
According to your mistakes, there is user interaction, so if you want to use a user token, you should not use Client Credential Flow but auth code flow, and grant client application Delegated permissions.
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&response_type=code
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&response_mode=query
&scope=api://11f5aca5-ba22-4b7b-8312-60a09aab7xxx/Files.Upload
&state=12345
POST /{tenant}/oauth2/v2.0/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&scope=api://11f5aca5-ba22-4b7b-8312-60a09aab7df5/Files.Upload
&code=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq3n8b2JRLk4OxVXr...
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&grant_type=authorization_code
&client_secret=JqQX2PNo9bpM0uEihUPzyrh
Parse the token and you will see your custom scp:

What value to give for "scope" option when I want to access an Azure function API that is protected with Azure AD in Postman

I am working on an Azure Function API that is protected by Azure AD, it's working fine when I request it with browser once I logged in with a valid account, but when I tried with postman it still shows unauthorized access,
I have got an access token to send with the request, but for the scope property I have given is this value, https://graph.microsoft.com/.default which I think might be the problem. But not sure what I am doing wrong and what to put in the scope field in the get new access tokenoption in postman to authenticate to my API.
HTTP Request Postman Making
GET /api/events/active HTTP/1.1
Host: moya-backend-ascentic.azurewebsites.net
Authorization: Bearer ****IHqMgweN86fDnyL4jvz9P6ZllpjjD9t***
User-Agent: PostmanRuntime/7.13.0
Accept: */*
Cache-Control: no-cache
Postman-Token: 655e0672-4928-409e-a709-841a92ee6f14,22cbf978-f196-4099-ae10-d162d3068507
Host: moya-backend-ascentic.azurewebsites.net
accept-encoding: gzip, deflate
Connection: keep-alive
cache-control: no-cache
The scope should be: your-api-client-id/.default.
Replace your-api-client-id with the client id/application id for your API app in Azure AD.
Now since browser-based login seems to be working, you may have setup the wrong kind of authentication on the API.
If the token still doesn't work, you'll need to setup JWT authentication on the app instead of browser/cookie based.
If you are using v2.0 endpoint, the scope should be {your_client_id}/.default. Just like #juunas said.
If you are using v1.0 endpoint, you only need resource parameter. The resource should be {your_client_id}
Note: If you are using the 'get new access token' function in postman, the Access Token URL should be https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token

Azure OAuth to function app issues

I have a very basic function app that takes a GET and returns some static text. Eventually I would like it to write a POST body to a queue but to keep it simple the function just returns text. If I keep auth off, I can load the url and get a response in my browser or postman. If I enable aad auth within the function app and create a simple app reg then goto the site in my browser I get prompted for auth and I can login interactively; no worries so far.
I would like to access the function using a secret key for application usage with no interactive login, so within the app reg I go to Keys and generate one. This is where my problems start. If I use postman and configure oauth using my app id and key I can get a token, I have verified this also by doing a POST to https://login.microsoftonline.com//oauth2/token directly and noting the bearer token reply. However when I try an access my function app using the bearer token (either by manually adding an Authorization header or letting postman add it from the oauth 2.0 form) I am always denied with a 401 stating 'You do not have permission to view this directory or page.' when I do a GET to my function app. Can someone point me in the right direction? Thanks in advance.
Example reply from login url
{
"token_type": "Bearer",
"expires_in": "3599",
"ext_expires_in": "0",
"expires_on": "1525312644",
"not_before": "1525308744",
"resource": "https://<siteaddress>.azurewebsites.net/",
"access_token": "eyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx..etc..."
}
Response from get against function app with token
GET /api/t2 HTTP/1.1
> Host: <sitename>.azurewebsites.net
> Authorization: Bearer eyxxxxxxxxxxxxxxxxxxxxxxxxxxxx.....etc....
> Accept: */*
< HTTP/1.1 401 Unauthorized
< Content-Length: 58
< Content-Type: text/html
< WWW-Authenticate: Bearer realm="<sitename>.azurewebsites.net" authorization_uri="https://login.windows.net/<tenantid>/oauth2/authorize" resource_id="<app reg id>"
< X-Powered-By: ASP.NET
< Date: Thu, 03 May 2018 01:12:43 GMT
I believe you're mixing Azure AD integration with function keys (API key authorization).
The latter is a self-contained authorization mechanism and works by appending
?code=<func-key-from-portal>
to the function URL, or by passing a
x-functions-key: <func-key-from-portal>
header with every request to the function. No OAuth is involved when using function keys.
Example:
GET /api/get-issues HTTP/1.1
Host: {funcapp}.azurewebsites.net
User-Agent: ajax-library-of-the-day
x-functions-key: rkW0PqT.....zcUBQ==
or
GET /api/get-issues?code=rkW0PqT.....zcUBQ== HTTP/1.1
Host: {funcapp}.azurewebsites.net
User-Agent: ajax-library-of-the-day

Clarification on REST APIs around user management in an account

I recently created a docusign developer account and integrator key and was playing with docusign REST APIs and had some questions
I can retrieve full list of users under my account by using following REST call.
https://demo.docusign.net/restapi/v2/accounts/<accountid>/users?additional_info=true
However if I try and retrieve a specific user (other than the one I am passing in my X-Docusign-authentication) header i get http 400 error with message that the "Invalid UserId. UserId specified in request uri does not match authenticated user"
https://demo.docusign.net/restapi/v2/accounts/<accountid>/users/0d51a699-b17a-48b7-95b6-1e9e9806deb6
In both cases i am sending the following header.
X-DocuSign-Authentication: <DocuSignCredentials><Username>{0}</Username><Password>{1}</Password><IntegratorKey>{2}</IntegratorKey></DocuSignCredentials>
I am surprised that while I can read all users fine, I cannot just read one specific user. Surely it doesn't seem like this is security thing since I can read the user via one API but not the other using the same auth token.
What am i missing?
I guess I can go the route of SOBO (Send on behalf of functionality), but I wanted to confirm if above behavior is expected.
Update#1
: I went the SOBO approach and now i get a different error (USER_NOT_ACCOUNT_ADMIN) as shown below
GET /restapi/v2/accounts/{accountid}/users/0fe29a55-5564-42a9-b09d-cbe699db13dd HTTP/1.1
Authorization: bearer {token for authenticating user}
X-DocuSign-Act-As-User: {operating user's email}
Accept: application/json
Host: demo.docusign.net
Connection: Keep-Alive
HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Content-Length: 100
Content-Type: application/json; charset=utf-8
Date: Thu, 17 Oct 2013 21:18:32 GMT
Strict-Transport-Security: max-age=7776000; includeSubDomains
{
"errorCode": "USER_NOT_ACCOUNT_ADMIN",
"message": "User is not an account administrator."
}
I also tried the second SOBO approach of getting a oauth token for the operating user but got back http 400 error with below message
{
"error": "invalid_request",
"error_description": "An OAuth2 error occurred."
}
So while i can get an oauth token for the autheitcating user, i am not able obtain oauth token for the operating user or act on their behalf.
I have made sure that authenticating user is "Account Administrator" and has both "apiAccountWideAccess" and "•allowSendOnBehalfOf" set to true. The only thing set to "false" is "canSendAPIRequests". My account id in sandbox environment is "601565a7-e9c7-463b-9d7c-622aed905ea8" Any ideas?
Update#2
Instead of generating oauth tokens on behalf of both authenticating user and operating user, i tried passing below header and i can finally get another user's profile and update another user's profile.
X-DocuSign-Authentication: <DocuSignCredentials><SendOnBehalfOf>{operating userid}</SendOnBehalfOf><Username>{authenticating userid}</Username><Password>{authenticating user's password}</Password><IntegratorKey>{developer's integrator key}</IntegratorKey></DocuSignCredentials>
Great!
So here is status of what works and what doesn't.
Works with no SOBO header anywhere
GET /restapi/v2/accounts/357938/users?additional_info=true // Read all users
GET /restapi/v2/accounts/357938/users?email=someshchandraatwork#gmail.com&additional_info=true // Read single user by email
POST /restapi/v2/accounts/357938/users // Add users
DELETE /restapi/v2/accounts/357938/users // Close users
*Works with SOBO in X-DocuSign-Authentication header
PUT /restapi/v2/accounts/357938/users/74a021e1-3090-4843-b9ab-cceb7cd119f4/profile // Update user's profile
GET /restapi/v2/accounts/357938/users/74a021e1-3090-4843-b9ab-cceb7cd119f4/profile // Read user's profile
Still doesn't work with or without SOBO**
GET /restapi/v2/accounts/357938/users/74a021e1-3090-4843-b9ab-cceb7cd119f4/settings
GET /restapi/v2/accounts/357938/users/74a021e1-3090-4843-b9ab-cceb7cd119f4
In both not working cases i get following error
Without SOBO i get error that userid doesn't match autheitcating user.
With SOBO i get error than user is not an account admin
I would very much appreciate any help in resolving the not working cases. I can provide more detaisl as needed.
Secondly I want to implement a scenario where I can deactivate a user in an account so they can no longer log into docusign. And subsequently I would like to enable that user back again with same permission that they had before they were disabled.
I see that user has a "userStatus" field and was wondering if I can use that to de-activate the user and then re-activate if needed. If this is supported then what value would correspond to deactivating the user?
The other thing I note is that on DELETE a user, the user is only soft-deleted since I can still query the user with the status "CLOSED". That would solve my "deactivate" problem. However I was not sure if there is a way to reactivate them back again after the user has been "closed"?
I believe this might be an account administration issue. I'm not sure why but I looked at your account settings from DocuSign's side and I saw the "Send on Behalf of" was not checked on your account- which is weird since it seems you have access to the setting in your Console -> Preferences settings.
But in either case I'm wondering if the setting I just enabled on your account has solved your issue, as it might have.
I'm also not sure about the user info portion of your question, let me see if I can come up with anything for that and I'll edit my answer once I do.
In reply to Erign's post above.
Anyone who is an account admin should be able to modify/add/delete users in an account. I'm not sure if your SOBO steps are correct though, can you confirm that you are following THESE STEPS exactly? If so, at which step do you run into issues or get an error?– Ergin5 mins ago
Yes i am following those steps. I am able to generate oauth token for the autheitcating user , but get an error when doing the same for the operating user. Below are my request and responses.
1. REQUEST FOR AUTH TOKEN FOR AUTHENTICATING USER
POST /restapi/v2/oauth2/token HTTP/1.1
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Host: demo.docusign.net
Content-Length: 139
Expect: 100-continue
Connection: Keep-Alive
grant_type=password&client_id={integratorykey}&username={authenticating user's email}&password={authenticating user's password}&scope=api
RESPONSE
HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Length: 100
Content-Type: application/json; charset=utf-8
Date: Thu, 17 Oct 2013 22:57:26 GMT
Strict-Transport-Security: max-age=7776000; includeSubDomains
{
"access_token": "{authenticating user's token}",
"token_type": "bearer",
"scope": "api"
}
2. REQUEST FOR AUTH TOKEN FOR OPERATING USER
POST /restapi/v2/oauth2/token HTTP/1.1
Authorization: bearer {authenticating user's token}
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Host: demo.docusign.net
Content-Length: 137
Expect: 100-continue
grant_type=password&client_id={integratorykey}&username={operating user's id}&password={empty}&scope=api
RESPONSE
HTTP/1.1 400 Bad Request
Cache-Control: no-cache
Content-Length: 87
Content-Type: application/json; charset=utf-8
Date: Thu, 17 Oct 2013 22:57:29 GMT
Strict-Transport-Security: max-age=7776000; includeSubDomains
{
"error": "invalid_request",
"error_description": "An OAuth2 error occurred."
}

Resources