Google OAuth token exchange returns invalid_code - oauth

I have been implementing the Google web server OAuth flow, but when I attempted to exchange the authorization code with access token, it always complains "invalid_code".
Here is the issue:
Step 1:
Redirect one of our pages to 'https://accounts.google.com/o/oauth2/auth?scope=email&redirect_uri=https%3A%2F%2Fmyurl.com%2Fcallback&response_type=code&client_id=some_client_id'
Step 2:
The redirection happens and google would redirect to our url
https://myurl.com/callback?code=somecode
Step 3:
curl -X POST --data "code=somecode&client_id=some_client_id&some_client_secret=some_client_secret&redirect_uri=https://myurl.com/callback&grant_type=authorization_code" https://accounts.google.com/o/oauth2/token -v --trace-ascii /dev/stout
The response comes back:
HTTP 400 Bad request
{
"error" : "invalid_grant",
"error_description" : "Invalid code."
}
Can someone help me with this issue? Thanks!

The life span of authorization code is only 10 mins,and can only be used one time. So do these checks:
Do you use it 10 min later? If so, use it in 10 mins.
Have you used it before? If so, obtain a new one and then use it.
Is you server time in sync with Google OAuth server's? If not, change your time.

I was using http://localhost:8080 as my redirect url since I was just trying out their examples. And my json file contents had this:
"redirect_uris": [
"http://localhost:8080"
],
"javascript_origins": [
"http://localhost:8080"
]
In the developer console I had the redirect_uri set to "http://localhost:8080" and I was getting the same error. I changed it to "http://localhost:8080/" and then it started working. (Essentially adding a '/' at the end.)
Hope this helps!

Related

YouTube Authorization Code exchange fails with redirect_uri_mismatch

I'm trying to exchange an authorization code for access code, but I'm getting an error saying "redirect_uri_mismatch".
I waited ~8 hours just in case it needs to update, but no luck so far.
The redirect uri's are set correctly, as you can see from the image here.
Initial Front-End redirect/request:
GET => https://accounts.google.com/o/oauth2/v2/auth
?scope=https://www.googleapis.com/auth/youtube.readonly
&include_granted_scopes=true
&state=state_parameter_passthrough_value
&redirect_uri=http://localhost:4200/profile?platform=youtube
&access_type=offline
&response_type=code
&client_id=[HIDDEN]
After code is parsed, I exchange the code for access code:
POST => https://oauth2.googleapis.com/token
?client_id=[HIDDEN]
&client_secret=[HIDDEN]
&code=[HIDDEN]
&grant_type=authorization_code
&redirect_uri=http://localhost:2222/youtube/oauth
Response:
data: {
error: 'redirect_uri_mismatch',
error_description: 'Bad Request'
}
Apparently, the redirect_uri has to match the initial request's uri.
Problem solved, feel free to upvote for visibility - thanks.
Source: https://www.rfc-editor.org/rfc/rfc6749#section-4.1.3

Can't deploy an app to Intune store via graph API - DeviceManagementApps.ReadWrite.All is an invalid scope?

We want to enable uploading apps to the Intune store via an API.
I saw this example on GitHub, and want to do something similar in JS, so I've tried using the same REST calls.
The problem is, I can't seem to make the https://graph.microsoft.com/beta/deviceAppManagement/mobileApps request properly - I always get 401. When making the same request via the Graph API Explorer it works fine.
I tried fixing my permissions, and I'm kinda stuck getting the correct token.
I did the following steps with an admin account, on both the "common" and our own tennant:
Called the admin consent - https://login.microsoftonline.com/nativeflow.onmicrosoft.com/adminconsent?client_id=<ID>&redirect_uri=<URI>
Got authorization from the user - https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=<ID>&response_type=code&redirect_uri=<URI>&response_mode=query&scope=DeviceManagementApps.ReadWrite.All
POST request to get the actual token -
https://login.microsoftonline.com/nativeflow.onmicrosoft.com/oauth2/v2.0/token
with the following body:
client_id: <ID>
scope: https://graph.microsoft.com/.default
client_secret: <secret>
grant_type: client_credentials
requested_token_use: on_behalf_of
code: <The code I got in step 2>
I tried changing the scope in step 3 to https://graph.microsoft.com/DeviceManagementApps.ReadWrite.All or simply to DeviceManagementApps.ReadWrite.All, but it says that it's not a valid scope.
I got a token in step 3, but when I try calling the actual API I receive this error:
{
ErrorCode:"Forbidden",
Message:{
_version: 3,
Message: "An error has occurred - Operation ID (for customer support): 00000000-0000-0000-0000-000000000000 - Activity ID: 7b5c3841-976d-4509-b946-f7fdabd047d7 - Url: https://fef.msub02.manage.microsoft.com/StatelessAppMetadataFEService/deviceAppManagement/mobileApps?api-version=5018-05-02",
CustomApiErrorPhrase: "",
RetryAfter: null,
ErrorSourceService: "",
HttpHeaders: {"WWW-Authenticate":"Bearer realm=urn:intune:service,f0f3c450-59bf-4f0d-b1b2-0ef84ddfe3c7"}
},
Target:null,
Details:null,
InnerError:null,
InstanceAnnotations:[]
}
So yeah, I'm pretty much stuck. Anyone have any experience with it? I've tried making the calls in Postman, curl and via code, but nothing works.
Cheers :)
You have a couple issues going on:
You're using the Authorization Code Grant workflow but requesting Client Credentials.
The scope Device.ReadWrite.All is an application scope, it is only applicable to Client Credentials. It isn't a valid Delegated scope so it will return an error when you attempt to authenticate a user (aka delegate) using Device.ReadWrite.All.
Your body is using key:value but it should be using standard form encoding (key=value).
To get this working, you need to request a token without a user. This is done by skipping your 2nd step and moving directly to retrieving a token (body line-breaks are only for readability):
POST https://login.microsoftonline.com/nativeflow.onmicrosoft.com/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id={id}
&client_secret={secret}
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&grant_type=client_credentials

Auth0 OAuth2.0 redirect 500

Is it ever expected to see a "500" status response during the final redirect from an OAuth2 provider?
server_error: Unable to issue redirect for OAuth 2.0 transaction
I'm trying to determine if this is ultimately the provider Auth0's error (it seems to be) or mine. If it were mine I'd expect a 400 series error. It is possible to have hooks or rules, could these result in 500-series errors in a scenario like this? I would also anticipate a more specific 500-error not 500 but another available number like 599 for lack of a better example.
My more specific case has something like:
new auth0.WebAuth({
domain: '....auth0.com'
,clientID: 'theid...'
,callbackUri: 'http://localhost:8080/'
,audience: 'http...',
,responseType: 'token id_token'
,scope: 'openid profile'
,leeway: 60
});
success then 500 for /login/callback?state=... on return
I misspelled the callback field, it should be redirectUri (not callbackUri above)! Auth0 tech support was kind enough to point this out.
I also asked about changing the error from 500 internal server error to 400 "Bad Request" to indicate a missing client-provided detail per my read of the details
https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
details for 400 (and the rest) https://www.rfc-editor.org/rfc/rfc7231#section-6.5.1

Coinbase Oauth2 - token request URL - "404 Not found"

First steps of the Coinbase Oauth Authorization seem to work fine.
I request the customer code via the following URL:
"https://www.coinbase.com/oauth/authorize?response_type=code&client_id=XXXXXXXXXXXXXXXXXXXX&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=user+balance"
I get back the code via URL..
Then trying to request the token with given CODE and CLIENT SECRET and CLIENT ID:
"https://api.coinbase.com/oauth/token&grant_type=authorization_code&code=XXXXXXX&redirect_uri=urn:ietf:wg:oauth:2.0:oob&client_id=XXXXXXX&client_secret=XXXXXXX"
With that I get an "404 Not found" Error..
Is there any obvious mistake in the URL.. or is it most likely an issue with the
Code or Secret etc. itself?
If Yes.. anything important to know there?
All that was followed from the description:
https://developers.coinbase.com/docs/wallet/authentication
Thank you so much for help!
The URL that you pasted:
https://api.coinbase.com/oauth/token&grant_type=authorization_code&code=XXXXXXX&redirect_uri=urn:ietf:wg:oauth:2.0:oob&client_id=XXXXXXX&client_secret=XXXXXXX
does not contain a query component since there's no ? character in there. You should rather use:
https://api.coinbase.com/oauth/token?grant_type=authorization_code&code=XXXXXXX&redirect_uri=urn:ietf:wg:oauth:2.0:oob&client_id=XXXXXXX&client_secret=XXXXXXX
and it looks like the documentation that you point to is the source of that error.
Moreover, the OAuth 2.0 spec says to use POST to the token endpoint, which is also stated in the docs but not clearly demonstrated in the sample. So you should send the parameters as form-encoded values an HTTP POST, e.g. the equivalent of the following cURL request:
curl -d "grant_type=authorization_code&code=XXXXXXX&redirect_uri=urn:ietf:wg:oauth:2.0:oob&client_id=XXXXXXX&client_secret=XXXXXXX" https://api.coinbase.com/oauth/token
Requesting it as a POST BODY did the job!
Although important changes:
- Redirect uri needs to be a proper external domain, uri for mobile apps will create a 401 Error..
-Encoding in ascii
import urllib
import urllib.request
import urllib.parse
data = urllib.parse.urlencode({'grant_type':'authorization_code', 'code': 'XXXXXX',
'redirect_uri': 'https://XXXXXX', 'client_id': 'XXXXXXXXXXX',
'client_secret' : 'XXXXXXXXXXX'})
binary_data = data.encode('ascii')
try:
response = urllib.request.urlopen('https://api.coinbase.com/oauth/token', data=binary_data)
print(response.status)
print(response.read())
except urllib.error.HTTPError as e:
print('%s %s' %(e.code, e.reason))
Got the rough structure from:
https://docs.python.org/3/library/urllib.request.html
Thanks a lot for the fast help!

Google oauth2.0 405 error

Im trying to use google oauth using the below link but get a 405 error,
Can you please let me know if the parameters are correct?
client_id = changed to a diff value
response_type = code
scope= openid%20email
redirecturl = given the value based on what I registered in console.developers.com
login_hint = my gmail id..
https://accounts.google.com/o/oauth2/token?
client_id=690178314820-85fvo4eq56se4mppdaf0pt6tnnjo552&
response_type=code&
scope=openid%20email&
redirect_uri=http://test.webfactional.com&
state=security_token%3D138r5719ru3e1%26url%3Dhttps://oa2cb.example.com/myHome&
login_hint=myemail#gmail.com
I made the above get requests in the browser..
There are a few steps to getting access to Google its easer for me to show you the full flow. My guess is you are stuck on step two because your not sending it as a post.
Step 1: Ask for access
https://accounts.google.com/o/oauth2/auth?client_id={clientid}.apps.googleusercontent.com&redirect_uri={From console}&scope=openid%20email&response_type=code
This just displays the window asking them to approve you. Once the user has approved access you get a one time Authentication Code.
Step 2: Exchange Authentication Code for AccessToken and RefreshToken. Note this needs to be sent as a HTTP POST not a HTTP Get.
https://accounts.google.com/o/oauth2/token
code={Authentication Code from step 1}&client_id={ClientId}.apps.googleusercontent.com&client_secret={ClientSecret}&redirect_uri=={From console}&grant_type=authorization_code
you should get a JSon string back looking something like this.
{
"access_token" : "ya29.1.AADtN_VSBMC2Ga2lhxsTKjVQ_ROco8VbD6h01aj4PcKHLm6qvHbNtn-_BIzXMw",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "1/J-3zPA8XR1o_cXebV9sDKn_f5MTqaFhKFxH-3PUPiJ4"
}
Now you can take that Access_token and use it to make your requests. But access tokens are only good for 1 hour and then they expire before that time you need to use the Refresh_token to get a new access token. Also if you are going to want to access your users data again you should save the refresh_token some place that will enable you to always access there data.
Step 3: Use Refreshtoken
https://accounts.google.com/o/oauth2/token
client_id={ClientId}.apps.googleusercontent.com&client_secret={ClientSecret}&refresh_token={RefreshToken from step 2}&grant_type=refresh_token
This time you will only get the Access token back, because your refreshtoken is good until the user removes authentication or you haven't used it for 6 months.
{
"access_token" : "ya29.1.AADtN_XK16As2ZHlScqOxGtntIlevNcasMSPwGiE3pe5ANZfrmJTcsI3ZtAjv4sDrPDRnQ",
"token_type" : "Bearer",
"expires_in" : 3600
}
You can find more detailed information on this here Google 3 Legged oauth2 flow
It seems you are using wrong api, you should use https://accounts.google.com/o/oauth2/auth instead of https://accounts.google.com/o/oauth2/token.
The reason you get error 405 is https://accounts.google.com/o/oauth2/token can only be called by POST, and it is to get token. You need to get authorization code first and then exchange it for a token.
Please pay attention for this /oauth2/v3/token and /oauth2/token
I do follow guide of google at this link
It show me following
obtain Authentication Code by /o/oauth2/auth => it work, the response as example in the guide
obtain access token by /oauth2/v3/token => it is error, the status code 405 is responsed
The correct must be /oauth2/token

Resources