I'm just not able to solve this for days now, anyone have any ideas? Below is the request response as shown by Fiddler
The response is that the oauth_signature is absent, however it was sent. If I calculated the signature incorrectly i would expect signature_invalid
I feel like the issue is staring me in the face, but I can't see it.
GET http://developer.messenger.yahooapis.com /v1/session HTTP/1.1
Authorization: OAuth
realm: "yahooapis.com"
oauth_version: "1.0"
oauth_token: "The oauth token "
oauth_nonce: "4724376"
oauth_timestamp: "1449488987"
oauth_consumer_key: "My consumer key"
oauth_signature_method: "HMAC-SHA1"
oauth_signature: "oBjiENcrXBX6I5dE/Vr7AHj2FOA="
Content-Type: application/json;charset=utf-8
Host: developer.messenger.yahooapis.com
HTTP/1.1 401 Authorization Required
Date: Mon, 07 Dec 2015 11:49:34 GMT
WWW-Authenticate: OAuth oauth_problem="parameter_absent: oauth_signature", realm="yahooapis.com"
Connection: close
Transfer-Encoding: chunked
Content-Type: application/xml
Cache-Control: private
17b
<?xml version='1.0' encoding='UTF-8'?>
Please provide valid credentials. OAuth oauth_problem="parameter_absent: oauth_signature", realm="yahooapis.com"
Many thanks
Jon
Found the problem:
I was creating a new request header for each authentication item. All the OAuth tokens must go in the same header. ie. the Authorization header
The code below is how I add create the Authorization header, which works fine now.
string OAuthHeader = "OAuth realm=\"yahooapis.com\"," +
"oauth_consumer_key=\"" + consumerkey + "\"," +
"oauth_timestamp=\"" + timestamp + "\"," +
"oauth_nonce=\"" + nonce + "\"," +
"oauth_version=\"1.0\"," +
"oauth_signature_method=\"PLAINTEXT\"," +
"oauth_token=\"" + dictGetRequestTokenParams["oauth_token"] + "\"," +
"oauth_signature=\"" + consumerSecret + "%26" + dictGetRequestTokenParams["oauth_token_secret"] + "\",";
request.Headers.Add(HttpRequestHeader.Authorization, OAuthHeader);
Related
I'm trying to implement a client that imports the events that a user has in Office 365 so that I can easily display them in the company's application.
I managed to get the user to authenticate with his / her Office 365 account and to approve my application and to also get an AccessToken, but when I try to use the token to retrieve the events from the API, I get a 401 HTTP error code, no body and in the headers I have this:
Content-Length →0
Date →Thu, 17 Mar 2016 08:56:00 GMT
Server →Microsoft-IIS/8.0
WWW-Authenticate →Bearer client_id="00000002-0000-0ff1-ce00-000000000000", trusted_issuers="00000001-0000-0000-c000-000000000000#*", token_types="app_asserted_user_v1 service_asserted_app_v1", authorization_uri="https://login.windows.net/common/oauth2/authorize", error="invalid_token",Basic Realm="",Basic Realm=""
X-BEServer →DB4PR06MB522
X-BackEndHttpStatus →401
X-CalculatedBETarget →DB4PR06MB522.eurprd06.prod.outlook.com
X-DiagInfo →DB4PR06MB522
X-FEServer →AM3PR06CA022
X-Powered-By →ASP.NET
request-id →de1963bc-36df-4473-81f6-66ec37e8b415
x-ms-diagnostics →2000001;reason="OAuth token submitted with the request can not be parsed.";error_category="invalid_token"
The token I get from https://login.microsoftonline.com/common/oauth2/token with the following body:
grant_type=authorization_code
redirect_uri=https://example.com/redirect-uri
client_id=XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXX
client_secret=[my-client-secret]
code=[code-received-from-user-auth]
The token I receive from the above call, I send through the Authorization header to https://outlook.office.com/api/v2.0/me/events like so:
Authorization: Bearer [access-token]
The response status I get from this call is 401 Unauthorized, I get an empty body and the headers are like so:
Content-Length →0
Date →Thu, 17 Mar 2016 08:56:00 GMT
Server →Microsoft-IIS/8.0
WWW-Authenticate →Bearer client_id="00000002-0000-0ff1-ce00-000000000000", trusted_issuers="00000001-0000-0000-c000-000000000000#*", token_types="app_asserted_user_v1 service_asserted_app_v1", authorization_uri="https://login.windows.net/common/oauth2/authorize", error="invalid_token",Basic Realm="",Basic Realm=""
X-BEServer →DB4PR06MB522
X-BackEndHttpStatus →401
X-CalculatedBETarget →DB4PR06MB522.eurprd06.prod.outlook.com
X-DiagInfo →DB4PR06MB522
X-FEServer →AM3PR06CA022
X-Powered-By →ASP.NET
request-id →de1963bc-36df-4473-81f6-66ec37e8b415
x-ms-diagnostics →2000001;reason="OAuth token submitted with the request can not be parsed.";error_category="invalid_token"
Can you please tell me what I'm doing wrong?
I managed to fix the problem I had.
For future reference, the problem was that I wasn't telling the https://login.microsoftonline.com/common/oauth2/token endpoint what I needed the token for.
I had to provide a resource parameter with the base url of the resource I was going to interogate after.
In my case, it was https://outlook.office365.com.
PROBLEM: I cannot authorize my connection to ASANA.
Breaking my code to the simplist bits. I used: http://onlinecurl.com/ to mimic what I see at
https://asana.com/developers/documentation/getting-started/authentication#sts=API%20Keys
This is my command.
curl --user 'NWE2MDJqUloubnpCUjh0d3gxVmYydW5BeFlJUER0Smw6' https://app.asana.com/api/1.0/users/me
Original : 5a602jRZ.nzBR8twx1Vf2unAxYIPDtJl
I even used https://www.base64encode.org/ to make sure my base64 was correct, which it is.
Response Header
1 HTTP/1.1 401 Unauthorized
2 Server: nginx
3 Date: Sat, 25 Oct 2014 17:58:23 GMT
4 Content-Type: application/json; charset=UTF-8
5 Transfer-Encoding: chunked
6 Connection: keep-alive
7 X-Asana-Content-String-Length: 41
8 Pragma: no-cache
9 Set-Cookie: TooBusyRedirectCount=0
10 Cache-Control: no-store
11 X-Asana-Preferred-Release-Revision: 20141024_201328_7ebcb21240775f3d5e6038b42ade419530485b76
12 X-Robots-Tag: none
Response Body
1{"errors":[{"message":"Not Authorized"}]}
How can I connect to the service with my Authorization???
Since writing this I have reset my aPIKEY
You do not need to base64-encode the username yourself, curl will do that for you. Also, please be careful of sharing your API key on public forums; these are sensitive credentials that should be treated like usernames and passwords! If that is a real API key I advise you reset it immediately (which you can do through the UI where you discovered it).
There needs to be a content Header
Here is what I did in Google Scripts.
In the site : http://onlinecurl.com/
we would need an extra option in headers for content-type
function getTasksFromAsana() {
api_key = "XXXX";
workspace_id = "WORKSPACE-ID";
// set up HTTPS connection
uri = "https://app.asana.com/api/1.0/users/me";
// set up the request
req={};
req = {
"headers":{ 'content-type': 'application/json','authorization': 'Basic ' + api_key }
}
Logger.log('Get Tasks Asana');
var response = UrlFetchApp.fetch(uri,req);
Logger.log(response.getContentText());
}
I am using the follow delphi code:
clHttp1.Request.Header.ContentType := 'application/x-www-form-urlencoded';
try
AccountKey:=Account;
clHttp1.Request.AddFormField('client_id',clientValue);
clHttp1.Request.AddFormField('client_secret',AccountKey);
clHttp1.Request.Header.Authorization:='Basic ' + Encode64(AccountKey + ':' + AccountKey);
clHttp1.Post('https://api.datamarket.azure.com/Bing/MicrosoftTranslator/v1/Translate?Text=%27developer%27&To=%27es%27&From=%27en%27', value);
except
on e: Exception do
ShowMessage(e.Message);
end;
And always receive error "the authorization type you provided is not supported. only basic and oauth are supported"
with response
HTTP/1.1 401 The authorization type you provided is not supported. Only Basic and OAuth are supported
Server: Microsoft-IIS/8.0
X-Content-Type-Options: nosniff
WWW-Authenticate: Basic Realm=""
X-Powered-By: ASP.NET
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: false
Access-Control-Allow-Headers: Authorization, DataServiceVersion, MaxDataServiceVersion
Access-Control-Expose-Headers: DataServiceVersion, MaxDataServiceVersion
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Max-Age: 604800
Date: Wed, 19 Nov 2014 09:40:24 GMT
Content-Length: 91
What I am doing wrong?
I'm trying to follow the documentation "https://developers.google.com/accounts/docs/OAuth_ref" to migrate oAuth to oAuth2 but keep getting an error
In the "APIs & auth" - "Credentials" Section in our API developers console we have 1 Client ID for web application set up along with a number of service account client Ids.
The client Ids appear to be in a format xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com for each client ID that is set up.
If I use the exact Id for the 'client ID for web application' in the format [xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com] then I get an error
{
"error" : "invalid_client"
}
If I use the more generic client ID [ xxxxxxxxxxxx.apps.googleusercontent.com
] then I get the following error
{
"error" : "disabled_client",
"error_description" : "The OAuth client was disabled."
}
Here is my post request from Fiddler
POST https://accounts.google.com/o/oauth2/token HTTP/1.1
Authorization: OAuth realm="",oauth_consumer_key="<consumerKey>",oauth_token="<token>",oauth_timestamp="1400680750",oauth_nonce="6637551",oauth_signature_method="HMAC-SHA1",oauth_signature="I%2FCOsR1BrGQHnqTeyhX4GUrKrv8%3D"
Content-Type: application/x-www-form-urlencoded
Host: accounts.google.com
Content-Length: 151
Expect: 100-continue
Connection: Keep-Alive
grant_type=urn:ietf:params:oauth:grant-type:migration:oauth1&client_id=<clientID>.apps.googleusercontent.com&client_secret={<client_secret>}
Here is the base string I use for oauth_signature
POST&https://accounts.google.com/o/oauth2/token&client_id=<clientID>.apps.googleusercontent.com&client_secret=<clientSecret>&grant_type=urn:ietf:params:oauth:grant-type:migration:oauth1&oauth_consumer_key=<consumerKey>&oauth_nonce=2648138&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1400681371&oauth_token=<token>
Here is the response I get from Google
HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Date: Wed, 21 May 2014 13:59:16 GMT
Content-Disposition: attachment; filename="json.txt"; filename*=UTF-8''json.txt
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Alternate-Protocol: 443:quic
Transfer-Encoding: chunked
5b
{
"error" : "disabled_client",
"error_description" : "The OAuth client was disabled."
}
0
Any suggestions?
Here a related post: https://groups.google.com/forum/#!topic/google-analytics-data-export-api/yveoPwSVzCQ
As for Owen's suggestion, I am pretty sure the error is not related to oauth1 vs oauth2 client type validation but rather to the provided oauth2 credentials (client id and client secret).
It turns out that the POST body that I was sending to google was incorrect.
Originally I had sent
grant_type=urn:ietf:params:oauth:grant-type:migration:oauth1&client_id=<clientID>.apps.googleusercontent.com&client_secret={<client_secret>}
Note the { } around the client_secret. When I removed these then I no longer got the errors.
Now I can pass in the client_id in the format xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com and the client_secret without { } and I get a sucessful response.
The reason for the other error that I had been receiving was that the client id in the format xxxxxxxxxxxx.apps.googleusercontent.com was an old client_id that had been deleted and was no longer visible on the Google Developer console.
I don't know what I do wrong, but everytime I tried to obtain the token (after user authentication of course), the result is always Invalid grant_type parameter or parameter missing
Possibly related to Box API always returns invalid grant_type parameter on obtaining access token
Here is my fiddler result:
POST https://api.box.com/oauth2/token HTTP/1.1
Host: api.box.com
Content-Length: 157
Expect: 100-continue
Connection: Keep-Alive
grant_type=authorization_code&code=nnqtYcoik7cjtHQYyn3Af8uk4LG3rYYh&client_id=[myclientId]&client_secret=[mysecret]
Result:
HTTP/1.1 400 Bad Request
Server: nginx
Date: Thu, 07 Mar 2013 11:18:36 GMT
Content-Type: application/json
Connection: keep-alive
Set-Cookie: box_visitor_id=5138778bf12a01.27393131; expires=Fri, 07-Mar-2014 11:18:35 GMT; path=/; domain=.box.com
Set-Cookie: country_code=US; expires=Mon, 06-May-2013 11:18:36 GMT; path=/
Cache-Control: no-store
Content-Length: 99
{"error":"invalid_request","error_description":"Invalid grant_type parameter or parameter missing"}
Even following the curl example gives the same error. Any help would be appreciated.
Edit: tried with additional redirect_uri params but still the same error
POST https://api.box.com/oauth2/token HTTP/1.1
Content-Type: application/json; charset=UTF-8
Host: api.box.com
Content-Length: 187
Expect: 100-continue
Connection: Keep-Alive
grant_type=authorization_code&code=R3JxS7UPm8Gjc0y7YLj9qxifdzBYzLOZ&client_id=*****&client_secret=*****&redirect_uri=http://localhost
Result:
HTTP/1.1 400 Bad Request
Server: nginx
Date: Sat, 09 Mar 2013 00:46:38 GMT
Content-Type: application/json
Connection: keep-alive
Set-Cookie: box_visitor_id=513a866ec5cfe0.48604831; expires=Sun, 09-Mar-2014 00:46:38 GMT; path=/; domain=.box.com
Set-Cookie: country_code=US; expires=Wed, 08-May-2013 00:46:38 GMT; path=/
Cache-Control: no-store
Content-Length: 99
{"error":"invalid_request","error_description":"Invalid grant_type parameter or parameter missing"}
Looks like Box requires a correct Content-Type: application/x-www-form-urlencoded request header in addition to properly URL encoding the parameters. The same seems to apply to refresh and revoke requests.
Also, per RFC 6749, the redirect_uri is only
REQUIRED, if the "redirect_uri" parameter was included in the authorization request
as described in Section 4.1.1, and their values MUST be identical.
I was facing a similar issue.
The problem is not with Content-Type.
The issue is with the lifecycle of code you receive.
One key aspect not mentioned in most places is that the code you get on redirect lasts only 30 seconds.
To get the access token and refresh token, you have to make the post request in 30 seconds or less.
If you fail to do that, you get the stated error. I found the info here.
Below code worked for me. Keep in mind, the 30-second rule.
import requests
url = 'https://api.box.com/oauth2/token'
data = [
('grant_type', 'authorization_code'),
('client_id', 'YOUR_CLIENT_ID'),
('client_secret', 'YOUR_CLIENT_SECRET'),
('code', 'XXXXXX'),
]
response = requests.post(url, data=data)
print(response.content)
Hope that helps.
You are missing the redirect URI parameter. Try:
POST https://api.box.com/oauth2/token HTTP/1.1
Host: api.box.com
Content-Length: 157
Expect: 100-continue
Connection: Keep-Alive
grant_type=authorization_code&code=nnqtYcoik7cjtHQYyn3Af8uk4LG3rYYh&client_id=[myclientId]&client_secret=[mysecret]&redirect_uri=[your-redirect-uri]
I have also face same issue implementing oauth2. I have add Content-Type: application/x-www-form-urlencoded. When I add content-type my issue solved.
Check and add valid content-type.
Not sure who might need this in the future but be sure you're sending a POST request to get the access token and not trying to retrieve it by using GET or if you're testing- pasting in the address bar won't work, you need to send a POST request with the data in the BODY and not as query parameter.
Also the code usually lasts for a few seconds, so you need to use it as soon as its sent back.