I'm using ForgeRock v7.1.0, running in Docker v3.6.0 on MacOS 11.5.2 (Big Sur).
I'm trying to exchange an OAuth 2.0 access token (subject token) I've already retrieved to be an ID Token (with a JWT Payload) and it's giving me an error every time I call it, specifically related I believe to the subject_token_type parameter.
The steps I am following are as follows:
Generate an OAuth2 access token:
curl --location --request POST 'http://am.example.com:8080/am/oauth2/realms/root/access_token' \
--header 'Authorization: Basic c3RldmU6cGFzc3dvcmQ=' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'username=user1' \
--data-urlencode 'password=7fYCi0Frhcq5p3gCXGxJ2B' \
--data-urlencode 'scope=cn'
which returns the following:
{
"access_token": "BS8vVbJ4EEygzdEE3jQH-xsKW9w",
"scope": "cn",
"token_type": "Bearer",
"expires_in": 3599
}
Introspect the token returned to check it's valid:
curl --location --request POST 'http://am.example.com:8080/am/oauth2/realms/root/introspect?token=BS8vVbJ4EEygzdEE3jQH-xsKW9w' \
--header 'Authorization: Basic c3RldmU6cGFzc3dvcmQ='
which returns the following:
{
"active": true,
"scope": "cn",
"realm": "/",
"client_id": "steve",
"user_id": "user1",
"token_type": "Bearer",
"exp": 1629990663,
"sub": "(usr!user1)",
"subname": "user1",
"iss": "http://am.example.com:8080/am/oauth2",
"auth_level": 0,
"authGrantId": "whjnenzHCH96TyaxfuefiOcBfm8",
"auditTrackingId": "4d353b7e-6cd5-4289-884a-39c50396ed0c-116027"
}
Now this is where I get the error, when I try to exchange the token:
curl --location --request POST 'http://am.example.com:8080/am/oauth2/realms/root/access_token' \
--header 'Authorization: Basic c3RldmU6cGFzc3dvcmQ=' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
--data-urlencode 'subject_token_type=urn:ietf:params:oauth:token-type:access_token' \
--data-urlencode 'subject_token=BS8vVbJ4EEygzdEE3jQH-xsKW9w' \
--data-urlencode 'scope=cn' \
--data-urlencode 'requested_token_type=urn:ietf:params:oauth:token-type:id_token'
which gives me the error:
{
"error_description": "Invalid token exchange.",
"error": "invalid_request"
}
If I don't specify the subject_token_type it instead gives me the error:
{
"error_description": "Subject token type is required.",
"error": "invalid_request"
}
which leads me to believe either I'm using the wrong type, or something isn't setup properly in my local instance of ForgeRock.
I've looked at the error response possibilities described here: https://backstage.forgerock.com/docs/am/7.1/oauth2-guide/token-exchange-flows.html but it's not that helpful.
Any help gratefully received! Thanks Steve
Doh! Always the way, after posting a question you manage to work it out!
OK, this is what I needed to do:
Navigate to Realm > [RealmName] > Scripts
Modify the "OAuth 2.0 May Act" Groovy script to be something like this (alter as appropriate):
import org.forgerock.json.JsonValue
token.setMayAct(
JsonValue.json(JsonValue.object(
JsonValue.field("client_id", "steve"),
JsonValue.field("sub", "(usr!user1)"))))
Validate and then Save the changes
Navigate to Realm > [RealmName] > Services > OAuth 2.0 Provider
Set the two ".. Token May Act Script" dropdowns at the bottom of the "Core" tab to the newly modified "OAuth2 May Act" script
Regenerate access tokens and repeat the Token Exchange call and it should work OK
Related
I am trying to get the repo details, of our comany bitbucket cloud.
using the API:
curl --request GET \
--url 'https://api.bitbucket.org/2.0/repositories/{workspace}/{repo_slug}' \
--header 'Authorization: Bearer <access_token>' \
--header 'Accept: application/json'
from
https://developer.atlassian.com/cloud/bitbucket/rest/api-group-repositories/#api-repositories-workspace-repo-slug-get
the problem is that every key/token I use, I get an error response of
{"type": "error", "error": {"message": "Access token expired."}}
I created an OAuth 2.0 key and secret and tried them both.
--header 'Authorization: Bearer <KEY>'
--header 'Authorization: Bearer <SECRET>'
I also tried App Password :
--header 'Authorization: Bearer <APP PASSWORD>'
also with SSH key:
--header 'Authorization: Bearer <SSH KEY>'
But I get the same error.
Thanks
I suggest that you omit the 'Authorization: Bearer' header completely, and use an app_password instead. In fact, Atlassian recommends the use of app passwords, allowing you to completely bypass the need for an access_token.
See the App passwords section of the Authentication Methods docs page.
Here's how it works. (Notice that the 'Authorization: Bearer' header is absent in these examples.) If your workspace is companyname, your username is prospero , and the app password you created per the Atlassian documentation is a1b2c3d4e5f6g7h8, then you can retrieve the list of repositories in this manner.
Curl:
curl -u prospero:a1b2c3d4e5f6g7h8 https://api.bitbucket.org/2.0/repositories/companyname
Python:
import requests
import json
r = requests.get('https://api.bitbucket.org/2.0/repositories/companyname', auth=('prospero', 'a1b2c3d4e5f6g7h8'))
print(r.text)
print(json.dumps(r.json(), indent=4))
Of course, you will want to use more sophisticated code. These are just quick examples.
Even though I read a numerous duplicate issues here on Stackoverflow, still can't figure out for the life of me what I'm doing wrong.
Problem: I successfully receive an authorization code from, but when I request an access token using this code I get the following error:
{
"error": "invalid_request",
"error_description": "Invalid parameter value for redirect_uri: Missing scheme: http%3A%2F%2Flocalhost%3A3030%2Fgoogle%2Foauth2%2Fcallback"
}
Configuration:
I use http://localhost:3030/google/oauth2/callback as a callback URL
It's setup in the google developer console:
This is a "raw curl" request that I send to obtain a token:
curl --location --request POST 'https://oauth2.googleapis.com/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'code=4%2F0AY0e-g6zyewnsWjPEXoxZWawsp1E634ZlefYoBeYO1nXxBwjPQNCGVf7SGb4MxfNcjUApw' \
--data-urlencode 'redirect_uri=http%3A%2F%2Flocalhost%3A3030%2Fgoogle%2Foauth2%2Fcallback' \
--data-urlencode 'client_id=....' \
--data-urlencode 'client_secret=....' \
--data-urlencode 'grant_type=authorization_code'
P.s. as you can see I "UrlEncoded" redirect_url as well as code since it does contain slashes. To be on the same side, I tried to encode client_id, client_secret and grant_type as well, but since they only contain ASCII characters they came out the same.
What I have done:
Researched through similar problems on SO: jenkins issue, ios issue, php issue, missing http issue,nodejs issue - similar to this one followed up by discussion, this, that, and all other ones present here - will omit them for brevity.
I've tried to set
http://localhost/google/oauth2/callback:3030 as well as
http://127.0.0.1:3030/google/oauth2/callback and
http://127.0.0.1/google/oauth2/callback:3000 (although specifying a port in the end is super weird and changing localhost to 127.0.0.1, but was suggested in one of the similar threads), none of these worked.
Read all the docs from google
Played with OAuth2 Playground (where it works obviously), but doesn't work for me
Tried multiple variations for body + different content types the same problem, but sometimes I also get
{
"error": "invalid_grant",
"error_description": "Bad Request"
}
Any help would be appreciated.
After some time I was able to successfully obtain a token. Turns out that I didn't craft request to Google API correctly. Also, for the "curl" request it should be --data rather than --data-urlencode. The following request worked for me:
curl --request POST \
--url https://oauth2.googleapis.com/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data code=4%2F0AY0e-g4TLGE7c7VyMe8-95baQzeh0uERiKuGnHG5Sqccb4MCsmJOzV_a2jSbI9bm62VZ6Q \
--data redirect_uri=http%3A%2F%2Flocalhost%3A3030%2Fgoogle%2Foauth2%2Fcallback \
--data client_id=********* \
--data client_secret=********* \
--data grant_type=authorization_code
or
curl --request POST \
--url https://oauth2.googleapis.com/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'code=4%2F0AY0e-g4TLGE7c7VyMe8-95baQzeh0uERiKuGnHG5Sqccb4MCsmJOzV_a2jSbI9bm62VZ6Q&redirect_uri=http%3A%2F%2Flocalhost%3A3030%2Fgoogle%2Foauth2%2Fcallback&client_id=*********&client_secret=*********&grant_type=authorization_code'
One more observation: When you test, you can use the authorization code only once (for security reasons). Sometimes even if you send multiple "unsuccessful requests" with the same code, Google's API will reject all subsequent requests with that code (you need to go through the OAuth2 again flow to obtain a new one). The most "frustrating" part that confused me is that the response for the wrong code looks like this:
{
"error": "invalid_grant",
"error_description": "Bad Request"
}
instead of being something like "Code is not valid" or "Code has expired".
So, if you encounter an error above it means the request was crafted correctly, but the code is wrong.
I want to implement token refresh for OAuth2 using Spring Cloud.
I can create token by sending request to /oauth/token using this payload:
curl --location --request POST 'http://localhost:8080/engine/oauth/token' \
--header 'Authorization: Basic YWRtaW46cXdlcnR5' \
--form 'username=admin' \
--form 'password=qwerty' \
--form 'grant_type=password' \
--form 'scope=read'
But for refresh token the same path /oauth/token is used. I need to send also username and password into the header 'Authorization: Basic YWRtaW46cXdlcnR5'which I don't have them. I can create a new token using using refresh token with this payload:
curl --location --request POST 'http://localhost:8080/engine/oauth/token' \
--header 'Authorization: Basic YWRtaW46cXdlcnR5' \
--form 'grant_type=refresh_token' \
--form 'scope=read' \
--form 'refresh_token=....'
Do you know how this issue can be solved?
Github code
The refresh token grant message does not need an Authorization header. Try removing it and sending client_id as a form parameter instead. You may also need to configure the offline_access scope for token refresh to work.
The last I remember though, token refresh is not supposed to be supported for ROPC, though that behaviour may not be the same for all providers.
Finally, be aware that ROPG is not really recommended if you have better options. This post summarises the issues.
If you can summarise your usage scenario I may be able to recommend a better alternative.
I'm looking to make a POST request to create an issue on my JIRA server. I was able to make a successful request using postman and basic authentication, but I would like to use the bearer method.
Here is my curl command:
curl --request POST--header 'Authorization: Bearer <token>'--header 'Accept: application/json'--header 'Content-Type: application/json'--data '{ "fields": { "project": {"key": "key"}, "summary": "Bug notification", "description": "THis is a test notification from cmd", "issuetype": {"name": "Bug"},"components": [{ "id": "0000"}], "priority": { "id": "2"}}}'--url 'https://server.atlassian.net/rest/api/2/issue'
Can someone please guide me on how to get the token, I have combed through a lot of documentation and nothing seemed to fit the bill?
you need to go to the api tokens page and create one from there
you need to create a token by following this instruction https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/
After the token is generated, you need to copy it and put some syntax below.
Get the issue example.
curl --request GET \
--url 'https://your-domain.atlassian.net/rest/api/2/issue/{issueIdOrKey}' \
--user 'email#example.com:<api_token>' \
--header 'Accept: application/json'
I've installed the Authorization extension in my Auth0 account, so authorization functionality works perfectly but now I want to access all the groups I've created there in that authorization extension. So I've followed Authorization docs but when I use the token I've generated for that it throws 403: Insufficient scope error in response.
These are the steps I've gone through:
1.Requested a token:
curl -X POST \
https://my_domain.auth0.com/oauth/token \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-d '{
"client_id":"auth0-authorization-extension-api-client-id",
"client_secret":"auth0-authorization-extension-api-secret",
"audience":"urn:auth0-authz-api",
"grant_type":"client_credentials"
}'
Response:
{"access_token":"encoded_access_token","expires_in":86400,"token_type":"Bearer"}
2.Requested group list:
curl -X GET \
https://domain.us.webtask.io/some_hash/api/groups \
-H 'authorization: Bearer access_token'
Response:
{
"statusCode": 403,
"error": "Forbidden",
"message": "Insufficient scope"
}
Hopefully this isn't a problem still for you, but if it is:
Go to your Auth0 dashboard
Click on APIs
You should have an API called auth0-authorization-extension-api
Select Non-interactive clients tab
Select the client you want to give access to and change toggle to Authorized
There's a drop down arrow beside the authorized toggle, click that and under scopes give access to read:groups. You may need read:users too.
Hope that helps, thanks
Kevin