I'm trying to get a user delegation SAS token for Azure Storage, using the REST API.
I've got an account, which has the required roles for the storage account, and the account has authenticated successfully and returned a Bearer token from the login endpoint.
When I request the user delegation key, I keep getting the following error:
<?xml version="1.0" encoding="utf-8"?>
<Error>
<Code>InvalidXmlNodeValue</Code>
<Message>The value for one of the XML nodes is not in the correct format.
RequestId:9b7a22e3-601e-0082-7bee-060981000000
Time:2021-02-19T18:38:48.1286734Z</Message>
<XmlNodeName>Expiry</XmlNodeName>
<XmlNodeValue>2021-02-19T19:30:00</XmlNodeValue>
</Error>
The body I'm submitting is copied from the Azure docs, :
<?xml version="1.0" encoding="utf-8"?>
<KeyInfo>
<Start>2021-02-19T18:30:00</Start>
<Expiry>2021-02-19T19:30:00</Expiry>
</KeyInfo>
Any idea what I'm doing wrong or missing for this to be failing?
The roles assigned on Azure are:
And the request headers:
Authorization: Bearer ...
x-ms-version: 2020-04-08
Content-Type: text/xml
User-Agent: PostmanRuntime/7.26.10
Accept: */*
Postman-Token: df276a57-747c-45dd-a849-15ac6ad7b45b
Host: ....blob.core.windows.net
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 147
The issue might be your token life time is too short to get it effective. My suggestion is, set the expiry time more than 8 hours longer than start time.
The value of the expiry time may be a maximum of seven days from the
start time.
Format your expiry time like this:
2021-02-19T19:30:00Z
Refer to: https://learn.microsoft.com/en-us/rest/api/storageservices/formatting-datetime-values
Related
I'm trying to read and write over a newly created azure table, but I kept getting 403 errors.
I'm using the same account that I used to create the table. I also added the account to the contributors group.
I've tested multiple scopes thinking does might be the issue, such as:
https://storage.azure.com/user_impersonation
https://storage.azure.com/.default
https://osnapdbexamsonthecloud.table.core.windows.net/.default
https://osnapdbexamsonthecloud.table.core.windows.net/user_impersonation
but always got the same error
Here is the requeset I'm sending:
PUT https://osnapdbexamsonthecloud.table.core.windows.net/exams(PartitionKey='Osnap',RowKey='test')
Accept: application/json;odata=fullmetadata
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.5
authorization: Bearer CENSORED
Connection: keep-alive
Content-Length: 27
content-type: application/json
Host: osnapdbexamsonthecloud.table.core.windows.net
Origin: http://localhost:3000
Referer: http://localhost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/109.0
x-ms-version: 2019-02-02
{"id":"test","temp":"test"}
And this is the response I get with status code 403:
{"odata.error":{"code":"AuthorizationPermissionMismatch","message":{"lang":"en-US","value":"This request is not authorized to perform this operation using this permission.\nRequestId:b3310a10-b002-0026-5cf5-3364d8000000\nTime:2023-01-29T15:22:15.9056626Z"}}}
Do you have any idea what I'm doing wrong?
I agree with #Gaurav Mantri, you need to assign Storage Table Data Contributor role to your Service Principal on that storage account.
I tried to reproduce the same in my environment and got the below results:
I have one storage account in which I created a table named exams like below:
Now, I generated an access token via Postman with the below parameters:
POST https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token
client_id: <appID>
client_secret: <secret>
grant_type:client_credentials
scope: https://storage.azure.com/.default
Response:
When I used the above token to perform the below operation, I got same error as you like this:
PUT https://sristorage30.table.core.windows.net/exams(PartitionKey='sri',RowKey='test')
Authorization: Bearer <token>
x-ms-version: 2019-02-02
{
"id":"test",
"temp":"test"
}
Response:
To resolve the error, try assigning Storage Table Data Contributor role to your service principal that can be your user account or Azure AD application.
In my case, I assigned that role to the service principal of App type like below:
Go to Azure Portal -> Storage accounts -> Your storage account -> Access control (IAM) -> Add role assignment
If you are performing the operation from your user account, assign that role to the service principal of User type like below:
The Azure Log Analytics API is returning this message:
{"Error":"InvalidAuthorization","Message":"An invalid signature was specified in the Authorization header"}
Even though the Authorization: SharedKey header is correct.
Turns out the Azure Log Analytics API does not support content type extensions and most modern http clients will generate a request header like this:
Content-Type: application/json; charset=utf-8
This will not work and you will get the cryptic response message above.
Overriding the header to simply:
Content-Type: application/json
Will fix the problem
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
I want to do something like the following page.
https://learn.microsoft.com/ja-jp/partner-center/develop/get-a-list-of-customers
Therefore, the required request header is as follows.
GET https://api.partnercenter.microsoft.com/v1/customers?size=40 HTTP/1.1
Authorization: Bearer <token>
Accept: application/json
MS-RequestId: 3705fc6d-4127-4a87-bdba-9658f73fe019
MS-CorrelationId: b12260fb-82de-4701-a25f-dcd367690645
However, I do not know how to obtain the required here.
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."
}