Not able to get access token from refresh token - office365api

i am getting this error while requesting for a new token from a refresh token in graph API.
can any i suggest please.
Thanks

It seems like you are forgetting to pass the grant_type, which tells the token service what it should be doing.
You should pass: grant_type=refresh_token
This information can be found in our documentation: Refreshing the access tokens
// Line breaks for legibility only
POST /{tenant}/oauth2/v2.0/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&scope=https%3A%2F%2Fgraph.microsoft.com%2Fmail.read
&refresh_token=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq...
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&grant_type=refresh_token
&client_secret=JqQX2PNo9bpM0uEihUPzyrh // NOTE: Only required for web apps

Related

Keycloak User Logout

I'm having trouble to allow users to logout from an application that uses Keycloak for access management.
I have found this topic being discussed here and there, but not clear instructions on how to handle the logout.
I tried to cause the logout of an user redirecting the browser to an endpoint of the following format:
https://example.com/auth/realms/myrealm/protocol/openid-connect/logout?id_token_hint=mytoken&post_logout_redirect_uri=https://example.com/initialpage/
What I used as "mytoken" was the access_token I had obtained making a post request to the endpoint:
https://example.com/auth/realms/playipintern/protocol/openid-connect/token
passing to it parameters like the ones bellow:
grant_type="authorization_code"
code=code_obtained_from_a_url_to_which_keycloak_redirected_the_browser
client_id=client_id_created_using_key_cloak_gui
redirect_uri=the_to_which_keycloak_redirected_the_browser
and reading the body of the response. The content of the body was a json, like the one bellow:
{
'access_token': 'long_token_I_used_latter_as_token_hint_trying_to_logout',
'expires_in': 300,
'refresh_expires_in': 1800,
'refresh_token': 'other_long_token',
'token_type': 'bearer',
'not-before-policy': 0,
'session_state': 'a_shorter_code',
'scope': 'email profile'
}
My logout attempt resulted in the following message in Keycloaks log:
22:53:51,686 WARN [org.keycloak.events] (default task-24) type=LOGOUT_ERROR, realmId=playipintern, clientId=null, userId=null, ipAddress=192.168.16.1, error=invalid_token
and the response said "We are sorry, session not active".
Now I'm aware that I should have used the id_token and not the access_token to logout, but received no id_token in the json.
Somewhere, someone said I should have included
scope=openid
in the parameters that I used to obtain the token. I did it, expecting to find an "id_token" field in the json, but nothing changed.
Someone else reported to have needed to create a scope (I believe using Keycloak's GUI) named "openid" to obtain the token. That didn't make much sense to me, but I tried it anyway and added the just created scope to the client scopes using Keycloak's GUI again. Oncemore, the json didn't change.
I tried to use the refresh_token as the id_token, but that also resulted in an invalid token message.
I don't know what to try now. Any help is appreciated.
Thank you.
/token endpoint returns only the access token by default. No refresh token is returned and no user session is created on the Keycloak side upon successful authentication by default. Due to the lack of refresh token, re-authentication is required when the access token expires. However, this situation does not mean any additional overhead for the Keycloak server because sessions are not created by default.
In this situation, logout is unnecessary. However, issued access tokens can be revoked by sending requests to the OAuth2 Revocation Endpoint as described in the OpenID Connect Endpoints section:
/realms/{realm-name}/protocol/openid-connect/revoke
Example:
POST /revoke HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
token=45ghiukldjahdnhzdauz&token_type_hint=access_token
You need to put your token in place of 45ghiukldjahdnhzdauz.
token_type_hint can take either access_token or refresh_token as value to define which type of token you want to revoke.
You will have to add scope=openid to your initial request to http://example.com/auth/realms/playipintern/protocol/openid-connect/auth (note the /auth instead of /token at the end) before the redirect from where you copied the access code.
You can find further information and explanation in this article.

How to revoke a token in Discord OAuth2.0?

In order to use Discord's API I need a token, and to get it I open a link such as
https://discordapp.com/api/oauth2/authorize?client_id=<client_id>&redirect_uri=<redirect_url>&response_type=token&scope=identify
Then I set the token as authorization (in format Bearer <token>) header of requests that are issued to the Discord's API.
Let's say I want to "logout", so that a certain token can't be used anymore to do such requests. In this case I have to revoke that token, right?
So after reading Discord's documentation and making some adjustments I decided that I have to make a POST request to a URL such as
https://discordapp.com/api/oauth2/token/revoke, and content-type header of this request should be set to x-www-form-urlencoded.
When I do it I'm getting an error message from discord's server with message saying {error: "invalid_client"}
What do I do wrong?
If you come by this question and are wondering what is the full API call to revoke the token, here it is:
POST https://discord.com/api/oauth2/token/revoke
Content-Type: application/x-www-form-urlencoded
data:
client_id: <client_id>
client_secret: <client_secret>
token: <access_token>
So the problem was in actual format of the data I was sending. I was sending JSON data because I thought that setting specific headers would automatically turn the data into the right format, but it turns out I had to use FormData object to create the data in the right format, and after that I also removed the lines where I'm setting the header explicitly, after these steps everything worked fine.

How to get new access token in OpenID Connect/OAuth2 Implicit Flow

I am currently using OpenID Connect/Oauth2 Implicit Flow in a mobile app. I am bringing up a Web View for the user to login and obtaining the access token and expiry. However, when the access token expires, do I need to ask the user to log in again? Or is there a way to get a new access token silently using the current one, without bugging the user. I guess another option is to set the token expiry to be a really long time, but I have read that this is a bad idea.
Am I missing something here?
Since Implicit flow does not send a refresh token (as explained in section 9 of RFC6746), usage of refresh tokens is not possible. But as a workaround one can use client credential grant to obtain an access token.
A viable solution is to first follow the implicit flow and authenticate the client. Then client authentication grant can be used to do the required API calls.
Sample request (from RFC6749)
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
rant_type=client_credentials
Sample resposne (from RFC6749)
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"example_parameter":"example_value"
}
P.S -
If you are using authorization code flow, you can use refresh_token to get a new access token. How the request should be formed can be obtained from OAuth2 documentation. Note that to do so, your authorization response should contain a `refresh_token.
A refresh token should be protected as valuable as a credential for a user. More can be read from keycloak documentation from here
Sample request and a response (from RFC6749)
Request
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
Response
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
"access_token": "TlBN45jURg",
"token_type": "Bearer",
"refresh_token": "9yNOxJtZa5",
"expires_in": 3600
}
The recommended way is to use an external browser and the Authorization Code Flow. Check the OAuth 2.0 for Native Apps RFC. For Android, there is also a supporting library AppAuth. With this flow, you can use a refresh token to get a new access token, but there is an issue with a client secret (usually needed for accessing /token endpoint), because you cannot keep it safe in a mobile app (it's described in the RFC).
If you decide to stick with the WebView and the Implicit Flow, which is not safe (your app can see the password) you could use the same technique as in JavaScript applications - request a new token with /auth?...&prompt=none URL which will return a new token without asking the user for credentials if he still has an open session there.

Google OAuth 2.0 redirect_uri_mismatch error for cross-client single-sign on

We are trying to implement Google's OAuth 2.0 cross-client sign-on functionality so that our server keeps the tokens and associates them with users, as shown in the diagram for the flow here: Google OAuth 2.0 Server-Side Flow
I am able to successfully retrieve a one-time access code on the client app. I then send that code to the server via a post to "http://example.com/oauth2callback/code="
It gets to the server just fine. The server then attempts a POST to Google that looks like this:
POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded
code={My Code}&
client_id={My Client ID}&
client_secret={My Client Secret}&
redirect_uri="http://example.com/oauth2callback"&
grant_type=authorization_code
However, each time the server is returning "Error: redirect_uri_mismatch."
We have tried everything. We double-checked the redirect_uri matches EXACTLY in the Google console and the client ID and client secret are correct. It still doesn't work. Any ideas?
In the "server-side" flow your redirect_uri should be set to postmessage. Unfortunately that is not clearly documented by Google. See also Google OAuth 2.0 "error" : "redirect_uri_mismatch" and related questions/answers.
We figured this out eventually, but I wanted to post this here so that others can find it. It turns out that you should NOT specify a redirect URI if you are exchanging a one-time access code for an access token via communicating with Google's servers from your own server. Instead, it should look like this:
POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded
code={My Code}&
client_id={My Client ID}&
client_secret={My Client Secret}&
redirect_uri=''&
grant_type=authorization_code

Can't get access token google drive sdk

I want to use Google drive api in my application, that's why I'm using OAuth 2.0 for Installed Applications. But I have a problem - I can't get an access token. At first I successfully get the authorization code using the following request:
https://accounts.google.com/o/oauth2/auth?
scope=https://www.googleapis.com/auth/drive.file&
redirect_uri=[my redirect_uri from from Developers Console]&
response_type=code&
client_id=[My client ID for native application from Developers Console]
Then I try to get an access token using received authorization code using the following request:
POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded
code={My uthorization code}&
client_id=[My client Id]&
client_secret=[My clien secret]&
redirect_uri=[my redirect_uri from from Developers Console]&
grant_type=authorization_code
All the time server returns 400. Can you tell me what could be the problem?
Trace the http request
Go to OAuth2 Playground and do the same
Spot the difference
It may be that you aren't urlencoding the params

Resources