Microsoft Oauth2 (token endpoint) - invalid client error - javascript

I am trying to get offline access to the outlook calendar from a webview.
(using the authorization_code oauth flow)
currently im doing the following
the javascript website calls the
https://login.microsoftonline.com/common/oauth2/v2.0/authorize
endpoint. Then I set the redirect URI to my spring endpoint.
The spring service is getting a valid code/state, so I assume I did everything correct until now.
Then I am calling the /token endpoint with the following parameters
{
grant_type: authorization_code,
client_id: <client_id>,
client_secret: client_secret,
redirect_uri: <THE SAME AS USED BY AUTHENTICATE>,
scope: https://graph.microsoft.com/mail.read
}
I am getting the following error back:
{
"error" : "invalid_client",
"error_description" : "The OAuth client was not found."
}
I made sure twice that the client secret/id is set correct. I used the microsoft registration portal to create my application, and Web as platform. Live SDK support is also enabled.
https://apps.dev.microsoft.com
Does anyone have suggestions why this doesnt work?

You need to pass back the authorization code you received from the first call in the body of your second call. The following are the parameters you need to pass back:
grant_type - Should be authorization_code
code - The auth code you received
client_id - This is your Application/Client ID
client_secret - This is the Password/Client Secret
scope - This should match the same set of scopes you initial requested
redirect_uri - This is the redirect URI defined in your application registration
Also keep in mind that the POST should encoded as application/x-www-form-urlencoded rather than application/json.
I wrote an primer on the v2 Endpoint that you might find useful here as well.

Related

Generate OAuth 2.0 Access Token For PUT Request In Google Sheets API In JavaScript

GOAL
I would like to update some information in a Google Sheets document though a web service. I don't mind if the data is public, but it seems like I need to get an OAuth token in order to use PUT https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/{range}as opposed to simply getting the data. However, I get back errors stating that I'm missing OAuth 2.0 credentials.
EXPECTATIONS
In order to do this, I assume that I need to first get credentials from Google's Developer Console . I currently have an OAuth 2.0 client ID and API key through that console. The API key is used to read the data and the OAuth would be used to write data.
I then need to hit an endpoint of some kind with the OAuth information to get credentials that'll be used. I'm supposed to put this info into my PUT request. This is the documentation I've found in regards to my request, but it's missing the authorization documentation.
QUESTIONS
1) Where is the endpoint that I'm hitting to get a refresh token and access token in Google's OAuth 2.0 stuffs? I've heard it's something like https://accounts.google.com/o/oauth2/token, but I'm not sure how to get the tokens. What do I need to pass? How do I pass that info? I can't find any documentation over it.
2) After getting these tokens, how do I incorporate them into the PUT request to the Google Sheets API? Do the tokens go into the Authorization header or the access_token query parameter or something?
I would highly recommend to check the Javascript Quickstart for Sheets API first as it includes OAuth sign-in demo.
From the quickstart code, this is the part that calls the OAuth library:
function handleClientLoad() {
gapi.load('client:auth2', initClient);
}
And here's me using the PUT request in an app I made:
function recordTimeInSheet(){
var params = {
"range":"Sheet1!"+A+":"+C,
"majorDimension": "ROWS",
"values": [
["bruceWayne","8:00AM", "5:00PM"]
],
}
var xhr = new XMLHttpRequest();
xhr.open('PUT', 'https://sheets.googleapis.com/v4/spreadsheets/'+myspreadsheetId+'/'+"values/"+"Sheet1!"+A+":"+C+"?"+'valueInputOption=USER_ENTERED');
xhr.setRequestHeader('Authorization', 'Bearer ' + myAccessToken);
xhr.send(JSON.stringify(params));
}

Create Groups in O365

Currently i am working on an App which will create groups in Office 365 programatically. I am wondering if this is possible using JavaScript. I also had another question regarding the Authentication and Authorization process. I am able to register the App and fetch the Authorization code. However when i try to fetch the Access token, it throws an error stating that it encountered a bad request. My Authorization URL is of the form:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?
client_id=<some_client_id>
&scope=openid+profile
&response_type=id_token
&redirect_uri=<some_redirect_url>
&nonce=123456789
And my access token request url is:
https://login.microsoftonline.com/common/oauth2/v2.0/token?
grant_type=authorization_code
&code=<Code_generated_in_above_request>
&redirect_uri=<some_redirect_url>
&resource=https%3A%2F%2Fgraph.microsoft.com%2F
&scope=openid+profile
&client_id=<some_client_id>
&client_secret=<Some_client_secret>
If anyone could help me regarding my doubts, then it would be greatly appreciated. Thanks.
Microsoft Graph from JavaScript
Using Microsoft Graph from JavaScript works. HTTP requests to the REST endpoints with a valid access token will work great. You might also want to check out KurveJS (github:MicrosoftDX/kurvejs) for a simple library (handles authentication and some graph operations).
Authentication
If you are attempting client-side implicit flow, you can pass 'response_type=id_token+token' and avoid the second call. This will return you an access token in the resulting payload.
If you are attempting server-side authentication, you should pass 'response_type=code' and then make the second call for the access token with the resulting code.
References:
v2.0 Protocols - SPAs using the implicit flow
v2.0 Protocols - OAuth 2.0 Authorization Code Flow

Google HTTP/REST OAuth: authorisation code request has state for db user, access token request has none

I am using the OAuth server flow for Google.
It starts with the user clicking a link that runs javascript to open a popup with the following request in the URI which is all working great:
var endpoint = "https://accounts.google.com/o/oauth2/auth";
endpoint = endpoint + "?scope="+encodeURIComponent(googlecalendar.SCOPES);
endpoint = endpoint + "&redirect_uri="+encodeURIComponent("https://myserver/google/");
endpoint = endpoint + "&response_type=code";
endpoint = endpoint + "&access_type=offline";
endpoint = endpoint + "&approval_prompt=force";
endpoint = endpoint + "&client_id="+encodeURIComponent(googlecalendar.CLIENT_ID);
endpoint = endpoint + "&state="+encodeURIComponent(googlecalendar.USER_ID);
On the server side, I get the state which contains the user_id for my DB and the authorisation code.
Now I want to exchange the authorisation code for access token (and renew token). This will be a HTTP request with a redirect URI, no state parameter is included.
The problem is that when I get those, I will need to store them against a user in my DB, but I don't have any way to check which user the callback is for.
The best I was able to come up with is using the token to query the google user's identity it belongs to but this still won't help me to find the user in the DB.
Can anyone help me with this flow? There must be some way to do. I don't want to use client libraries because later when I need to create watchers the PHP client library does not include this for the calendar API.
Short Answer
Despite the presence of a redirect parameter, the access token will generate a standard 200 response, not a 301 redirect. Depending on how you issue and handle the request/response, you can preserve your state.
More Detailed Answer
According to section 4.1.4 of the OAuth 2.0 spec document (RFC 6749), the response to an Access Token Request should be an "HTTP/1.1 200 OK".
In other words, the server will not perform a redirect, meaning you can issue a request and process the response in the same scope (either in the client or server, whatever your situation), so your database user ID need only be in local memory.
This is different from the Authorization Request, which is supposed to result in an "HTTP/1.1 302 Found" (redirect). See section 4.1.2.
So why is the redirect_uri parameter required?
According to section 4.1.3, the server must:
ensure that the "redirect_uri" parameter is present if the "redirect_uri" parameter was included in the initial authorization request as described in Section 4.1.1, and if included ensure that their values are identical.
In other words, the redirect_uri acts as a sort of secret or password which the server must use to verify the access token request. If the client fails to provide a redirect_uri parameter, or the parameter value is different from the original request, then the server must reject the access token request.

Facebook Same Window Authentication

I am trying to do Facebook authentication in same window of my web application's login page.
I am using following code when user clicked login button to go to authentication page.
function loginUsingOAUTH()
{
top.location = 'https://graph.facebook.com/oauth/authorize?client_id=839846246064537&scope=email&redirect_uri=http://www.olcayertas.com/testqa/result.html';
}
1) After authentication Facebook redirects me to my redirect url and returns a parameter "code".
At this point I want to access Facebook user information but I don't know how to do that.
What is this "code" parameter for?
2) Is there any other way to access user information?
3) Do you have any other advice facebook authentication with same window login?
Thank you in advance for your help
When you get the code you should make a server side request to get an access token and than pass the access token to user. It is explained in Facebook Developer page:
Exchanging code for an access token
To get an access token, make an HTTP GET request to the following
OAuth endpoint:
GET https://graph.facebook.com/v2.3/oauth/access_token?
client_id={app-id}
&redirect_uri={redirect-uri}
&client_secret={app-secret}
&code={code-parameter}
This endpoint has some required parameters:
client_id. Your app's IDs
redirect_uri. This argument is required and must be the same as the original request_uri that you used when starting the OAuth login
process.
client_secret. Your unique app secret, shown on the App Dashboard. This app secret should never be included in client-side code or in
binaries that could be decompiled. It is extremely important that it
remains completely secret as it is the core of the security of your
app and all the people using it.
code. The parameter received from the Login Dialog redirect above.
Response
The response you will receive from this endpoint will be returned in
JSON format and, if successful, is
{“access_token”: <access-token>, “token_type”:<type>, “expires_in”:<seconds-til-expiration>}
If it is not successful, you will receive an explanatory error
message.

Sending Request 2.0 app-generated request to other than "/me"

I am trying to send app-generated request using either JS SDK or graph API but I am not successful and desperate. Issue is that when I am sending request to currently logged user, everything is ok, but when I try to send to different user (even this user already authorized my app) I receive OAuth exception "#2 User can't send this request: Unknown error", sometimes "Failed to send any app requests".
My app has Request 2.0 enabled and is authorized with publish_stream, read_stream and user_about_me permissions. Same error messages I described are shown even in Graph API explorer.
Exactly same issue is described here using JS SDK:
Sending an App Generated Request with the JavaScript SDK
... and here using Graph API:
Posting app generated apprequest to other facebook users in Java
Please help.
If you want send a request to a user, you should POST to the Graph API '/user_id/apprequests' using an App Access Token (https://developers.facebook.com/docs/authentication/#applogin). This call is to design to be executed server-side as you don't want to share your App Access Token:
curl -F 'access_token=APP_ACCESS_TOKEN' \
-F 'message=From the app to the user.' \
https://graph.facebook.com/USER_ID/apprequests
The same can be achieve using the User Access Token from the recipient (USER_ID) only:
curl -F 'access_token=USER_ACCESS_TOKEN' \
-F 'message=From the app to the user.' \
https://graph.facebook.com/USER_ID/apprequests
In the JS SDK, if no Access Token field is added, the default Access Token will be of the logged in user. Knowing that, the above call which send the a request to the logged in user, will be:
FB.api('/me/apprequests', 'POST', {message: 'From the app to the user.'});
The first call can also be done with the JS SDK, by adding the App Access Token in the parameters. However, this is a DO NOT USE case as you don't want to share your App Access token client-side.

Categories

Resources