"The access grant authorization_code is not supported" from Azure AD using Oauth 2 - azure

I am in the middle of an Authorization Code Grant Flow with Azure AD. Even though the documentation says the grant_type should be authorization_code, I am getting an error message about this property.
POST https://login.windows.net/SOME_AZURE_AD_UUID/oauth2/token?api-version=1.0
Content-Type: application/x-www-form-urlencoded
client_id=SECRET_CLIENT_ID
&client_secret=SECRET_CLIENT_SECRET
&code=SECRET_CODE
&grant_type=authorization_code
&redirect_uri=https://myserver.example.com/login/auth_return
&resource=https://myserver.example.com/
&scope=openid email
(edit: whitespace added for clarity)
The error I am getting back:
HTTP/1.1 400 Bad request
Content-Length: 436
X-Content-Type-Options: nosniff
X-Powered-By: ASP.NET
Request-Id: SOME_REQUEST_ID
X-Ms-Request-Id: SOME_REQUEST_ID
Strict-Transport-Security: max-age=31536000; includeSubDomains
Set-Cookie: x-ms-gateway-slice=slicea; path=/; secure; HttpOnly, stsservicecookie=acs; path=/; secure; HttpOnly
Server: Microsoft-IIS/8.0
Cache-Control: private
Date: Wed, 20 Aug 2014 14:44:08 GMT
Content-Type: application/json; charset=utf-8
{
"correlation_id": "SOME_CORRELATION_ID",
"error": "unsupported_grant_type",
"error_codes": [
70003
],
"error_description": "
ACS70003: The access grant 'authorization_code' is not supported.\r\n
Trace ID: SOME_TRACE_UUID\r\n
Correlation ID: SOME_CORRELATION_ID\r\n
Timestamp: 2014-08-20 14:44:08Z",
"timestamp": "2014-08-20 14:44:08Z",
"trace_id": "SOME_TRACE_UUID"
}
(whitespace added for clarity)
This request does work if I change grant_type to client_credentials (but I have not found a way to use the resulting token for what I need). It also works if I change some URLs to point to Google instead of Azure AD.
Is there a mistake with these requests or does the service genuinely not support the documented grant_type of authorization_code?

This is a bug I believe, and it took me 2-3 days to figure it out. Please do the following to get it working,
1) Remove the "?api-version=1.0" from your URL. I know it sounds strange but trust me their documentation is a mess.
2) Add a "Content-Type": "application/x-www-form-urlencoded" header in your request (hence you'll have to encode the post data values ... for example redirect_url=(encodedURL) etc
3) Remove unnecessary fields from post data REFER ... it should be like
{
'grant_type': "authorization_code",
'resource': "your resource",
'client_id': "your client Id",
'redirect_uri': "your redirect URL",
'client_secret': "your client secret",
'code': "the code u got"
}
I see you have done point 2 so you'll need to do point 1 and you're good to go.
Furthermore, if you want to get access_token quickly(if nothing I said works for you), then pass "client_credentials" in grant_type and you'll get a smaller response with access_token. But if you want the complete response with refresh_token as well, you'll have to do all those steps.
EDIT:
There is one more mistake in their documentation, for Refresh Tokens >>> the URL should be oauth2/token and NOT oauth2/authorize
Hope this helps!

try this
'grant_type':"client_credentials",
'resource': "your resource",
'client_id': "your client Id",
'redirect_uri': "your redirect URL",
'client_secret': "your client secret",

Related

DocuSign, Node SDK, JWT auth, Envelope fetch, "The custom error module does not recognize this error."

[FINAL UPDATE]
Fixed per this thread: https://github.com/docusign/docusign-esign-node-client/issues/295
Apparently related to security additions made to DocuSign's API.
I haven't encountered this issue before today. I gave a demo to a client just last week and the same code was working fine. Today I get the following:
{
"status": 444,
"response": {
"req": {
"method": "GET",
"url": "https://demo.docusign.net/restapi...",
"data": {},
"headers": {
"user-agent": "node-superagent/3.8.2",
"x-docusign-sdk": "Node",
"authorization": "Bearer ABC...",
"content-type": "application/json",
"accept": "application/json"
}
},
"header": {
"content-type": "text/html",
"x-docusign-tracetoken": "2eeb8caa-8865-4898-bef9-d3611bfaa3f7",
"x-docusign-node": "DA2DFE5",
"date": "Fri, 17 Jun 2022 01:02:02 GMT",
"content-length": "54",
"connection": "close",
"strict-transport-security": "max-age=31536000; includeSubDomains"
},
"status": 444,
"text": "The custom error module does not recognize this error."
}
}
Through the node SDK I fetch a token using requestJWTUserToken, and set the apiclient's auth header, then I new-up an EnvelopesAPI instance. When I make a call to getEnvelope() or listStatusChanges(), then I get the error above. None of this code has changed in months, and I'm using the same integration key, account, private key, everything. I've demo'd it all a few times now - no issues.
An interesting observation: the error above gives me a URL and token. The token is valid, and if I make a request to the URL (the envelopes endpoint) via Postman using said token, then the request succeeds. So my calls through the SDK seem to be failing for some reason.
I can't seem to crack this one, and now I can't get around it given a couple demo systems that worked just last week.
I'm using the docusign-esign 5.17 module - upgraded from 5.15 in an attempt to fix the issue. No luck.
Where is this error coming from?
[Update 1]
I'm running my node app that is making requests through the DocuSign Node SDK against a proxy so I can see what the failing request actually look like:
They fail the same way.
HTTP/1.1 444
Content-Type: text/html
X-DocuSign-TraceToken: 338534c6-c8c3-4b01-9b66-35d697cd0053
X-DocuSign-Node: DA1DFE4
Date: Fri, 17 Jun 2022 03:55:07 GMT
Content-Length: 54
Vary: Accept-Encoding
Connection: close
Strict-Transport-Security: max-age=31536000; includeSubDomains
The custom error module does not recognize this error.
I'm using Proxyman to catch the request, and like Chrome or Firefox it will let you copy a request as a cURL command. If I copy the failing request as cURL, then run in at the terminal, it succeeds.
[MacBookPro0020]~/source/docusign/jwt-smoke-test:0 (master)
$ curl 'https://demo.docusign.net/restapi/v2.1/accounts/a0a4c81f-.../envelopes?envelope_ids=e750526f-...&envelope_ids=a38b794b...&envelope_ids=a5d8c586-...' \
-H 'Host: demo.docusign.net' \
-H 'User-Agent: node-superagent/3.8.2' \
-H 'X-DocuSign-SDK: Node' \
-H 'Node-Ver: v14.18.3' \
-H 'Authorization: Bearer ABCD...' \
-H 'Accept: application/json' \
-H 'Connection: close' \
-H 'Content-Type: application/json' \
--proxy http://localhost:9090
{"resultSetSize":"1","startPosition":"0","endPosition":"0","totalSetSize":"1","nextUri":"","previousUri":"","envelopes":[{"status":"created","documentsUri":"/envelopes/d97565c8...purgeState":"unpurged","envelopeIdStamping":"true","autoNavigation":"true","isSignatureProviderEnvelope":"false","allowComments":"true","anySigner":null,"envelopeLocation":"current_site"}]}
I'm using a JWT auth token, so again, I'm getting a valid token. Calls through the SDK consistently fail, but cURL'ing and manually requesting through Postman both succeed.
I'm at a loss.
Additional details: I see this same issue on MacOS and Windows (i.e., node app hosting docusign-esign). I'm using auth code grant to send envelopes and query envelope statuses and that works fine. I've used JWT Grant without issue up until this week (just demo'd automated functionality last week and it worked.) I haven't made any code changes to my DocuSign functionality, nor have my colleagues, at least according to the repo's history.
I don't recall ever encountering the error above before. I'd love to know why cURL'ing the same request succeeds. I'd rather not ditch the SDK and roll my own requests, but it wouldn't be difficult.
[Update 2]
Here's a simple repro - it's a quick and dirty copy of the QuickStart demo project for the node SDK. I'm using only docusign-esign.
Exact. same. issue.
Again, I can take that token and drop it into cURL or postman and the request will succeed. There's not a lot of code here. The token is valid.
async function main() {
// Data used
// dsConfig.dsClientId
// dsConfig.impersonatedUserGuid
// dsConfig.privateKey
// dsConfig.dsOauthServer
let dsConfig = dsConfig_customer; // defined globally
const jwtLifeSec = 10 * 60, // requested lifetime for the JWT is 10 min
dsApi = new docusign.ApiClient();
dsApi.setOAuthBasePath(dsConfig.dsOauthServer.replace('https://', '')); // it should be domain only.
const results = await dsApi.requestJWTUserToken(dsConfig.dsClientId,
dsConfig.impersonatedUserGuid, 'signature impersonation', dsConfig.privateKey,
jwtLifeSec);
console.log( results.body.access_token );
const userInfo = await dsApi.getUserInfo(results.body.access_token);
dsApi.setBasePath(userInfo.accounts[0].baseUri + '/restapi');
dsApi.addDefaultHeader( 'Authorization', 'Bearer ' + results.body.access_token );
const envelopesAPI = new docusign.EnvelopesApi(dsApi);
const res = await envelopesAPI.getEnvelope( dsConfig.accountID, 'e1917111-2900-48e8-9054-799169379c8a', null );
console.log(res);
return {
accessToken: results.body.access_token,
tokenExpirationTimestamp: expiresAt,
userInfo,
account: userInfo.accounts[0]
};
}
main().then(result => console.log(result)).catch(err=>console.error(err));
...
header: {
'content-type': 'text/html',
'x-docusign-tracetoken': '685b6226-a0d3-4547-94c7-df0216d884a3',
'x-docusign-node': 'DA2DFE188',
date: 'Fri, 17 Jun 2022 05:20:12 GMT',
'content-length': '54',
vary: 'Accept-Encoding',
connection: 'close',
'strict-transport-security': 'max-age=31536000; includeSubDomains'
},
statusCode: 444,
status: 444,
statusType: 4,
info: false,
ok: false,
redirect: false,
clientError: true,
serverError: false,
error: Error: cannot GET /restapi/v2.1/accounts/49754554-ABCD-.../envelopes/e1917111-2900-48e8-9054-799169379c8a (444)
...
I finally manage to resolve the issue by downgrading my Docusign SDK NodeJS version from 5.15.0 to 5.7.0 in my package.json file.
An issue relative to this can be find there, I really hope this issue will be resolved anytime soon.
Edit :
The Docusign support actually took action on this (the github's issue from above is now closed), it might be interesting to test again with the latest version of Docusign SDK NodeJS (or the one you were using previously).

Etag support for S/4 EX

Etag is supported in SDK: https://sap.github.io/cloud-sdk/docs/java/features/odata/use-typed-odata-v4-client-in-sap-cloud-sdk-for-java/#handling-of-etags
So experimenting it by using BusinessPartner entity in S/4 EX.
But seems there's no If-Match header:
How come the header doesn't show up - any prerequisite with etag?
(entering on behalf of the implementation partner team)
I checked the VersionIdentifier of the response and it was not set to a value.
I also checked the response's JSON __metadeta and header, but there were no values that appeared to correspond to the ETag value.
[Code]
BusinessPartner bp1 = new DefaultBusinessPartnerService().getBusinessPartnerByKey(bpId).execute(dest);
log.debug("get 1: {}", bp1);
log.debug("get 1 VersionIdentifier: {}", bp1.getVersionIdentifier());
bp1.setOrganizationBPName1("SCP Update 1st:" + System.currentTimeMillis());
ODataUpdateResult result1 = new DefaultBusinessPartnerService().updateBusinessPartner(bp1).execute(dest);
log.debug("Update1 Http Status: {}", result1.getHttpStatusCode());
bp1.setOrganizationBPName1("SCP Update 2nd:" + System.currentTimeMillis());
bp1.setVersionIdentifier("dummy");
ODataUpdateResult result2 = new DefaultBusinessPartnerService().updateBusinessPartner(bp1).execute(dest);
log.debug("Update2 Http Status: {}", result2.getHttpStatusCode());
[Log]
get 1: BusinessPartner(super=VdmObject(customFields={}, changedOriginal...
get 1 VersionIdentifier: None
Update1 Http Status: 204
Update2 Http Status: 204
[GET Response JSON(__metadata) / Response Header]
(It has masked the IP address.)
"__metadata": {
"id": "https://xxx.xxx.xxx.xxx:xxxxxx/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner('1000001')",
"uri": "https://xxx.xxx.xxx.xxx:xxxxxx/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner('1000001')",
"type": "API_BUSINESS_PARTNER.A_BusinessPartnerType"
},
HTTP/1.1 200 OK
content-type: application/json; charset=utf-8
content-length: 3152
dataserviceversion: 2.0
sap-metadata-last-modified: Thu, 14 May 2020 23:58:07 GMT
cache-control: no-store, no-cache
sap-processing-info: ODataBEP=,crp=,RAL=,st=,MedCacheHub=SHM,codeployed=X,softstate=
sap-server: true
sap-perf-fesrec: 243070.000000
I tried setting the VersionIdentifier to a meaningless value in my test code (2nd update).
The update process seems to be successful, although the request header now has "If-Match" added to it.
(I was expecting the update to fail because the values never match, so I was hoping the update would fail.)
[2nd Update(setVersionIdenfifier)]
(It has masked some of the values.)
PATCH http://xxx.xxx.xxx.xxx:xxxxxx/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner(BusinessPartner='1000001') HTTP/1.1
x-csrf-token: xxx
Content-Type: application/json
Accept: application/json
If-Match: dummy
Authorization: Basic xxx
SAP-Connectivity-SCC-Location_ID: xxx
Proxy-Authorization: Bearer xxx
sap-language: en
sap-client: xxx
Content-Length: 55
If ETags are not part of OData service responses, then you should approach the IT/administrators who maintain the S/4 backend. The SAP Cloud SDK is only consuming the OData service. Unfortunately it can't leverage ETag support if it's disabled.

How do I pass the username/password to authenticate a POST request to a Django rest-framework API from python code?

this is the request I want to emulate in python code, made here with httpie
$ http --auth mucho:pass POST http://3333333.ngrok.io/sms/ msg="love conquers all" to="255123456"
HTTP/1.1 201 Created
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 67
Content-Type: application/json
Date: Mon, 30 Dec 2019 20:31:33 GMT
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
{
"id": 70,
"msg": "love conquers all",
"owner": "mucho",
"to": "255123456"
}
I have tried this
from requests import Request,Session
url="http://3333333.ngrok.io/sms/"
data = {
"to": "255123456",
"msg": "love conquers all",
}
s=Session()
req=Request('POST',url,data=data)
preped=req.prepare()
preped.prepare_auth(("mucho","pass"),url)
resp=s.send(preped)
It works, but I am looking for a neater/simpler way possibly using headers. Thanks for any help my way
If you are looking for a way to test your api endpoints, you can use insomnia or postman.
It is easy to set the headers.

Getting code=OrganizationFromTenantGuidNotFound while updating group using Microsoft Graph

I am getting the below exception
"error": {
"code": "OrganizationFromTenantGuidNotFound",
"message": "The tenant for tenant guid '****' does not exist.",
"innerError": {
"request-id": "2acd6af1-99f8-4aab-b71d-cffc60263a05",
"date": "2019-04-20T11:33:04"
}
while updating the group using open extension as shown below: -
POST https://graph.microsoft.com/v1.0/groups/db5f4dbe-40e0-4352-84fb-9a20c131cfaf/extensions HTTP/1.1
Authorization: Bearer ****
Content-Type: text/plain; charset=utf-8
Host: graph.microsoft.com
Content-Length: 111
Expect: 100-continue
Connection: Keep-Alive
{ "#odata.type":"microsoft.graph.openTypeExtension","extensionName":"com.test.nickName","date":"OpenExtension"}
I am using user***#outlook.com id and having active azure subscription. I have given all delegated permission to microsoft graph.
Content type was not specified and it was going as text. Error handling could be improved. After changing content type to "application/json", it is working perfectly fine.
POST https://graph.microsoft.com/v1.0/groups/db5f4dbe-40e0-4352-84fb-9a20c131cfaf/extensions HTTP/1.1 Authorization: Bearer **** Content-Type: application/json; charset=utf-8 Host: graph.microsoft.com Content-Length: 111 Expect: 100-continue Connection: Keep-Alive
{ "#odata.type":"microsoft.graph.openTypeExtension","extensionName":"com.test.nickName","date":"OpenExtension"}

How to use Microsoft.Graph with client authorization and not get a 401

We have
created Azure Active Directory
created a new Application
registered the new Application in Azure AD
given ALL the permissions to the API
granted admin permissions
Now we login with this app credentials
We get authorization:
GET /1111111-aaaa-4fd3-bf32-9bfc460f67b1/oauth2/v2.0/authorize HTTP/1.1
Host: login.microsoftonline.com
cache-control: no-cache
Postman-Token: 111111-aaaa-4696-9828-9110670706c5
We get the token:
POST /11111111-aaaa-4fd3-bf32-9bfc460f67b1/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
cache-control: no-cache
Postman-Token: 11111111-aaaa-47e4-b2fb-6b94cd02312a
client_id=11111111-aaaa-482e-ab17-86e4c2c6240c
scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
client_secret=aaaaaaaaaaaDJk6jBJ%2FuBRJM6AFxyFIDMKn867hmvU%3D
grant_type=client_credentials
The token analyzed with jwt.io:
{
"aud": "https://graph.microsoft.com",
"iss": "https://sts.windows.net/1111111-ccc6-4fd3-bf32-9bfc460f67b1/",
"iat": 1541603660,
"nbf": 1541603660,
"exp": 1541607560,
"aio": "42RgYFB+/Gyh8uF3yl+uKU7km//kFwA=",
"app_displayname": "ToDoListService",
"appid": "1111111-4e99-482e-ab17-86e4c2c6240c",
"appidacr": "1",
"idp": "https://sts.windows.net/1111111-ccc6-4fd3-bf32-9bfc460f67b1/",
"oid": "1111111-98fb-4a47-af7f-d3800dde2f7b",
"roles": [
"Chat.UpdatePolicyViolation.All",
"Calls.JoinGroupCall.All",
"EduRoster.Read.All",
"OnlineMeetings.Read.All",
"Mail.ReadWrite",
"OnlineMeetings.ReadWrite.All",
"Device.ReadWrite.All",
"User.ReadWrite.All",
"Domain.ReadWrite.All",
"Application.ReadWrite.OwnedBy",
"SecurityEvents.Read.All",
"Calendars.Read",
"EduAssignments.ReadWrite.All",
"People.Read.All",
"Application.ReadWrite.All",
"Calls.InitiateGroupCall.All",
"Group.Read.All",
"Directory.ReadWrite.All",
"EduAssignments.ReadWriteBasic.All",
"MailboxSettings.Read",
"EduAdministration.Read.All",
"Calls.JoinGroupCallAsGuest.All",
"Sites.Read.All",
"Sites.ReadWrite.All",
"Contacts.ReadWrite",
"Group.ReadWrite.All",
"Sites.Manage.All",
"SecurityEvents.ReadWrite.All",
"Notes.Read.All",
"User.Invite.All",
"EduRoster.ReadWrite.All",
"Files.ReadWrite.All",
"Directory.Read.All",
"User.Read.All",
"EduAssignments.ReadBasic.All",
"EduRoster.ReadBasic.All",
"Files.Read.All",
"Mail.Read",
"Chat.Read.All",
"ChannelMessage.Read.All",
"EduAssignments.Read.All",
"Calendars.ReadWrite",
"identityriskyuser.read.all",
"EduAdministration.ReadWrite.All",
"Mail.Send",
"ChannelMessage.UpdatePolicyViolation.All",
"MailboxSettings.ReadWrite",
"Contacts.Read",
"IdentityRiskEvent.Read.All",
"AuditLog.Read.All",
"Member.Read.Hidden",
"Calls.AccessMedia.All",
"Sites.FullControl.All",
"Reports.Read.All",
"Calls.Initiate.All",
"Notes.ReadWrite.All"
],
"sub": "1111111-98fb-4a47-af7f-d3800dde2f7b",
"tid": "1111111-ccc6-4fd3-bf32-9bfc460f67b1",
"uti": "hxPwbjRRm0y6SI8hxuckAA",
"ver": "1.0",
"xms_tcdt": 1541414851
}
You can see that we get all the necesary permissions.
And this petition works:
https://graph.microsoft.com/v1.0/Users/
or
https://graph.microsoft.com/beta/Users/
but not this one:
https://graph.microsoft.com/beta/Users/<user-id>/Calendars
nor this one:
https://graph.microsoft.com/beta/users/<user-id>/sendMail
they both return 401:
{
"error": {
"code": "UnknownError",
"message": "",
"innerError": {
"request-id": "019ddc83-6528-4f19-95cc-8b99ea53a046",
"date": "2018-11-07T16:03:55"
}
}
}
I think that we had got all the necessary permission, configuration... etc... so why isn't it working? :'(
[UPDATE]
detailed call to get calendars
GET /v1.0/Users/<user-id>/Calendars HTTP/1.1
cache-control: no-cache
Postman-Token: xxxxxxxxxxxxxxxxxxxxxxx
Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
User-Agent: PostmanRuntime/7.3.0
Accept: */*
Host: graph.microsoft.com
accept-encoding: gzip, deflate
Connection: close
Response
HTTP/1.1 401 Unauthorized
Cache-Control: private
Transfer-Encoding: chunked
Content-Type: application/json
request-id: 11111111-aaaa-aaaa-a115-e09bb6f09917
client-request-id: 11111111-aaaa-aaaa-a115-e09bb6f09917
x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"North Europe","Slice":"SliceC","Ring":"3","ScaleUnit":"001","Host":"AGSFE_IN_34","ADSiteName":"NEU"}}
Duration: 377.0084
Strict-Transport-Security: max-age=31536000
Date: Thu, 08 Nov 2018 09:16:03 GMT
Connection: close
c6
{
"error": {
"code": "UnknownError",
"message": "",
"innerError": {
"request-id": "2bb9a7c1-f8a3-4c1f-a115-e09bb6f09917",
"date": "2018-11-08T09:16:04"
}
}
}
0
let me start by first of all noticing that you have posted a client secret on a public forum :) And one that has luxurious permission on your tenant. I hope you have changed the client secret by now.
But to get back to your question - I will have to ask a bit more in detail to get a better understanding of what your actual results were:
According to your JWT printout you are getting a V1 token but using the client credential flow (the field "ver" is set to 1.0). The Microsoft Documentation here Get access without a user explicitly states that you should use a V2 Token to access Microsoft Graph in this scenario. So the first question is: Did you create your Azure App using the V2 Portal: https://apps.dev.microsoft.com/ ? If not then this may be the issue.
A more common issue when manually testing - Have you made sure that the token had not expired from the time you got it from the /token endpoint up to the time you tested your API call?
If none of the above - please post your request to the https://graph.microsoft.com/beta/Users//Calendars endpoint in detail, the devil may be in the details

Resources