I am trying to integrate Microsoft Azure Active directory in my application,
Here's what I have able to achieve so far and where I am stuck -
1.
My URI to request an Authorization code -
https://login.microsoftonline.com/{{tenant-id}}/oauth2/authorize?
response_type=code%20id_token
&scope=openid
&response_mode=query
&redirect_uri=http://localhost:8081/dashboard.html
&client_id={{client-id}}
&nonce={{nonce}}
&site_id={{site_id}}
I have been able Authenticate the user and successfully redirect the authenticated user to the redirect_uri page,
My Front end received 3 things from AD after successful redirection -
a) id_token
b) code
c) session_state
2.
Using these I am able to successfully ake a post call to the Microsoft endpoint, to receive Access tokens, following are the call details -
Endpoint - https://login.microsoftonline.com/{{tenant-id-here}}/oauth2/token
Type - Post
Headers - Content-Type
Body(application/x-www-form-urlencoded) - grant_type, code, client_id, redirect_uri, client_secret, resource
3.
Microsoft endpoint responds with following data -
a) token_type
b) expires_in
c) ext_expires_in
d) expires_on
e) access_token
f) refresh_token
g) id_token
4.
Now as per the OAuth process, my Front end passes the access_token on every API call, this access_token is supposed to be verified by hitting some Microsoft endpoint, which I believe is the following one -
Endpoint - https://graph.microsoft.com/v1.0/me/messages
Type - Get
Header - Authorization
Header value - Bearer {{Access-token}}
Parameters - client_id
Error message -
This request if failing with 404
Can someone help me understand -
1. Am I hitting the correct endpoint to verify the access_token?
2. If yes what a I doing wrong?
3. If no, which is the correct endpoint? and what should be it's request details?
Here are my reference docs -
1. https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-code
2. https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-code
Tried hitting the following endpoint as well -
Endpoint - login.microsoftonline.com/{{tenant-id}}/oauth2/authorize
Type - Post
Header - Authorization, Content-Type
Header value for Authorization- Bearer {{Access-token}}
Header value for Content-Type- application/x-www-form-urlencoded
Body(application/x-www-form-urlencoded) - client_id
Try specifying the resource parameter.
Even though it is said to be optional, it is included in every sample here: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-code.
So when you retrieve the tokens from https://login.microsoftonline.com/{tenant-id}/oauth2/token, remember to include the resource parameter, and set its value to https://graph.microsoft.com to get tokens to use on Microsoft Graph API.
I can also say that in your screenshot you are not passing the access token in the header. That looks like an authorization code or refresh token. You must pass the access token.
Related
I am using FusionAuth for authentication. I have created one application in the FusionAuth. It has oAuth configured.
http://localhost:9011/oauth2/authorize?access_type=offline&prompt=consent&response_type=code&client_id=9ecc54b7-6f79-4105-a208-ca61e6157b58&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fipos%2Frest%2FfusionAuth%2FcallBack
This is my authorization url to one the FusionAuth login page.
Once I hit the link and enter the user name and password, I get the call back on configured call back url in my java jersey api.
I get the following details in the call back request.
code - dZgq5Xd0YmAQXZ2JIzkih832iojimgLUPwT7yoH9-TY
locale - en_US
userState - AuthenticatedNotRegistered
Here I am using Scribe Java library for OAuth authentication
I make call to get the access token call usnig the Scribe java libary with the given authorization code and grant_type is authorization_code.
Here this call get success and I get the below detail in the response.
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImRRZTA1Uk1vN19oVjZUUnpLVUQ1aXpRU2NSOCJ9.eyJhdWQiOiI5ZWNjNTRiNy02Zjc5LTQxMDUtYTIwOC1jYTYxZTYxNTdiNTgiLCJleHAiOjE1Nzc3MTg0NjgsImlhdCI6MTU3NzcxODM0OCwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiI3ZWE3OWRhZi1hZjExLTQ1MTUtODljYS1iOGFjYTFjN2I5YTEiLCJhdXRoZW50aWNhdGlvblR5cGUiOiJQQVNTV09SRCIsImVtYWlsIjoiZGhhdmFsYmhvb3Q5M0BnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwicHJlZmVycmVkX3VzZXJuYW1lIjoiZGhhdmFsYmhvb3QifQ.eA0Xi6nEZhWaTMd-P26ESdE3NsyXNRNVBKBdBvHxvzfHgXYJiN2pf-16mY8JK-4-1g3vZF7Cwv-SkP4iZAIJCYYc3uBW8Qlcjjn9cyi7_RggBBBsErcs2acRIt-D5NpnVJfkxHwGAs9fO6a2Win98GGYyv1nzBG9OhWkyZJTy4QxzlgXNrkQIzTuzRwLkRFzKCT95pqfsOYb_MXPuAksg5q1SHIj8qtbO7EO-vMbpmiok1C-Wflbiq2X_tq17QBKbO4JAMLm9_pCZse1tqLyNP4fIh3VHTz7OdbbXvug2Tpk_yTWLVL_29XC87-91R5iXeezLjADkdi1yXMUdHioOw",
"expires_in": 119,
"token_type": "Bearer",
"userId": "7ea79daf-af11-4515-89ca-b8aca1c7b9a1"
}
Here, I do not get the refresh_token, in any case, user first time login or in any case.
This is JWT token and I had reduced the expiry time to 120 seconds.
In application OAuth setup I enable Generate refresh tokens option.
The only problem here I have is, I do not receive the refresh token.
Help me with this.
Thank you.
To obtain a Refresh Token as a result of the Authorization Code Grant, you'll need to request the offline_access scope.
https://fusionauth.io/docs/v1/tech/oauth/endpoints#authorization-code-grant-request
You can modify your request as follows (line breaks added for readability)
http://localhost:9011/oauth2/authorize?
scope=offline_access
&prompt=consent
&response_type=code
&client_id=9ecc54b7-6f79-4105-a208-ca61e6157b58
&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fipos%2Frest%2FfusionAuth%2FcallBack
As a side note, adding prompt=consent is fine, but it will not affect the request as this is not yet available in FusionAuth. Please upvote the feature request if this is something you'd like to see in an upcoming release. https://github.com/FusionAuth/fusionauth-issues/issues/411
I have some questions regarding an API JWT refresh token workflow using Java Spring.
I have this so far:
User logs in to /users/login - if successful a response with 2 headers is returned Authorization and Refresh. Which contain 2 tokens - one with short 30 mins expiration and one with longer 4 hours expiration.
He can then access all other endpoints using the Authorization header.
If at some point accessing an endpoint his token is expired he receives an error (UNAUTHORIZED).
And has to do a request to /token/refresh with the refresh token he was given.
Questions:
I have set it up so authorization token has a claim: type=auth and
the refresh token has a claim: type=refresh. What is the best way to
distinguish the two tokens.
What should be the error in step 3 (instead of unauthorized) to distinguish it from a request without a valid token
/token/refresh doesn't ask for authentication currently. Should it?
Should the /token/refresh endpoint be a POST with header, POST with parameters or a GET with header.
What is the best way to distinguish the two tokens.
Refresh token does not have to be a JWT at all. I prefer to simply generate a random alphanumeric string. Refresh token does not carry any additional information. It requires a lookup to database to confirm validity of refresh token. You distinguish them by where they appear in your request. Authorization token (access token) should appear in a header of your choice.
What should be the error in step 3 (instead of unauthorized) to distinguish it from a request without a valid token
Sending 401 Unauthorized is exactly the way to do it. 401 tells the client, that he cannot access the resource now, but he can take actions so that he can access the resource again (login/refresh token). 403 on the other side would tell the client, that the resource does not belong to him and he will have to ask for permissions, e.g. by contacting an admin
/token/refresh doesn't ask for authentication currently. Should it?
No, there is no need for authentication.
Should the /token/refresh endpoint be a POST with header, POST with parameters or a GET with header.
Generally a GET endpoint should be read only and not mutate any resources. POST and PUT endpoints are intended for mutations. In this, I'd use a POST with parameters and a dedicated URL, e.g. /token/refresh
I connect to the Internet-store WooCommerce through a WooCommerce REST API using Java Retrofit library.
When I build simple queries such as "example.com/wp-json/wc/v1/products/categories" or "example.com/wp-json/wc/v1/orders" - all OK - passes authentication and I get a JSON result.
I look in the logs on the Android Monitor - in the case of successful authentication to log output here this URL:
http://example.com/wp-json/wc/v1/products/categories?oauth_signature_method=HMAC-SHA1&oauth_consumer_key=ck_0fadf0f69b271063373f49a6cd942ce995d5dad4&oauth_version=1.0&oauth_timestamp=1478702999&oauth_nonce=-56787616&oauth_signature=AmEJUMnKzKxkqETQoQxd07WRvZo&page=2
But if I try to use in query parameters such as "example.com/wp-json/wc/v1/products/categories?per_page=20" or "example.com/wp-json/wc/v1/orders?page=3" - I get an error authorization 401.
I tried different variants of queries:
add a parameter in Retrofit.Builder().baseUrl("example.com/wp-json/wc/v1/products/categories?per_page=20")
add a parameter in the call of interface functions - Call<.....> loadCategories(#Query("per_page") Integer 20)
add a parameter when forming an authorization string in the Interceptor after oauth_signature - .addQueryParameter("per_page", "20")
The logs URL takes the form type:
http://example.com/wp-json/wc/v1/products/categories?per_page=20&oauth_signature_method=HMAC-SHA1&oauth_consumer_key=ck_0fadf0f69b271063373f49a6cd942ce995d5dad4&oauth_version=1.0&oauth_timestamp=1478702999&oauth_nonce=-56787616&oauth_signature=AmEJUMnKzKxkqETQoQxd07WRvZo&page=2
The error occurs when I add parameter after ? - I understand it conflicts with the authorization parameters WooCommerce?
What am I doing wrong? Or maybe it was a error WooCommerce API ?
I am using an API to get some information. At the beginning of each session you need to get a JWT token to be able to send requests to the API. After I've got the token and I try to send a request, I get an error saying I'm unauthorized, which is fair since I did not attach the token in my request. The problem is that the documentation for the API does not explain how to do this, and I haven't been able to find it anywhere else either. How do I do this? I am doing this is Java and is using their own HttpURLConnection. Hopefully you understand what I mean.
Thank you in advanced!
It depends on how the web-service (API) wants to have the token represented.
Common are:
HTTP request headers (problem for XHR requests)
query parameters (bad idea because of caching/logging)
form fields (not universally useable)
URL segment (bad idea because of caching/logging)
certain cookies with the token as value (transparent) or
authentication header (typical)
The Authentication headers as defined in HTTP RFCs are typically be used with the Basic or Digest authorization scheme. In case a string (token) authenticates the bearer of that token, the "Bearer" scheme is used (for example defined for OAuth2 in RFC6750).
You would use
uc.setRequestProperty("Authorization","Bearer " + jwt);
for this.
I am stucking with the following problem like one month already, I am trying to verify an inapp purchase by using the following api :https://developers.google.com/android-publisher/authorization
I followed every step from the documentation(doing everthing with Postman Rest Client from Chrome), I can retrieve an accesstoken and a refresh token, but whenever when I try to query a purchase it results in error code 403 access not configured, BUT I CONFFIGURED IT IN THE SETTINGS!
anybody with an idea maybe?
It is far from straightforward to get an accesstoken for this API. This blog post helped get me started in the right direction, but I've outlined my own process that does not depend on using any external scripts to work. The steps are:
Obtain a client ID and secret (one-time)
Obtain a Refresh Token (one-time)
Use the Refresh Token to obtain an Access Token (once per hour)
4 Use the access token to access the API
Each of these steps are detailed below:
Obtaining Client ID and Secret
Go to the the Google Developer's console
Go to your project page
Select "Consent Screen" on the left side and make sure that the email address and Product name fields are set
Select "Credentials" from the left menu, and select "create a new client id"
Leave Application type set to "Web application" and set "Authorized redirect URI" to https://localhost. You do not need to change the Authorized JavaScript Origins.
Click "Create Client ID" and record the Client ID and Client secret that result.
Obtaining a Refresh Token
In web browser, enter the following URL (substituting correct value for client_id):
https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&access_type=offline&redirect_uri=https://localhost&client_id=XXXX
Accept any requests for authorization that appear
You will then be redirected to a URL like this:
https://localhost/?code=4/k0TenvwICIgmBoQOazJy4_EnJr6-.clLqtp_vVAIbEnp6UAPFm0GASPqQigI
Copy the code from the latter part of this URL
Use wget to convert this code into refresh token; substitute CODE, CLIENT_ID, and CLIENT_SECRET
wget --debug --post-data="grant_type=authorization_code&code=CODE&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&redirect_uri=https://localhost" https://accounts.google.com/o/oauth2/token
The resulting JSON file will contain an access_token and a refresh_token. Record the refresh_token value
Obtaining an Access Token
send a POST request to https://accounts.google.com/o/oauth2/token with the following fields set (substitute REFRESH_TOKEN, CLIENT_ID, CLIENT_SECRET)
grant_type=refresh_token
refresh_token=REFRESH_TOKEN
client_id=CLIENT_ID
client_secret=CLIENT_SECRET
You will get back a JSON string containing an access_token that will be good for one hour.
Using the Access Token to make API request
Fetch from
https://www.googleapis.com/androidpublisher/v1.1/applications/PACKAGENAME/inapp/SKU/purchases/PURCHASETOKEN
with an Authorization header containing the access token, e.g:
Authorization: Bearer ya29.1.AADtN_WoM4-4Fb1voFL-emcUWluijCzwvc9Z-FYM9SPvK03HCbGkdROJTVVPSLHK2IlVJQ
You may also be able to pass the access token as an HTTP query parameter, e.g.
https://www.googleapis.com/androidpublisher/v1.1/applications/PACKAGENAME/inapp/SKU/purchases/PURCHASETOKEN?authorization_token=AUTHTOKEN
I had a similar problem as you. Answer by mmigdol is helpful, but it didn't help me. I finally managed to solve it by looking at links generated here: https://developers.google.com/oauthplayground/
Apparently, Android publisher scope
https://www.googleapis.com/auth/androidpublisher
needs to be added into the link requesting authorisation code (before even generating refresh token) by adding:
&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fandroidpublisher
to get this:
https://accounts.google.com/o/oauth2/auth?redirect_uri=<YOUR_REDIRECT_URI>&response_type=code&client_id=<YOUR_CLIENT_ID>&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fandroidpublisher&approval_prompt=force&access_type=offline