I am using IAP to protect a Web API Application. I have enabled a service account to get access to the APIs through an id_token. I am able to obtain an id_token (JWT) by signing a JWT (using the keys of my service account) with the following assertions
{
"iss": "xx.iam.gserviceaccount.com",
"sub": "xx.iam.gserviceaccount.com",
"aud": "https://oauth2.googleapis.com/token",
"target_audience": "my_application_client_id",
"iat": 1598702078,
"exp": 1598705593
}
and then Posting to the token service as follows
curl --location --request POST 'https://oauth2.googleapis.com/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'assertion=<JWT obtained at the previous step>’
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' \
--data-urlencode 'scope=openid’
Now I would like to also obtain a refresh_token and has been impossible. I have tried with scope=openid offline_access but no luck. Is offline_access implemented in the Google Auth Server? Any other mechanism to obtain a refresh_token?
According to the documentation here, for the OpenID server flow you would need to use access_type as parameter set to offline for it to work. There are more details here.
Related
I have created a PubSub schema
I have created an API key with no restrictions
I wish to cURL/Get this schema from an address outside of GCP
I tried the below request but it's denied as per below
me#J-5CG2200NLY:~/go/$ curl https://pubsub.googleapis.com/v1/projects/myprojetc199/schemas/pbschema_1?key=mylongkeyxxxxxxxxxxxx
{
"error": {
"code": 403,
"message": "User not authorized to perform this action.",
"status": "PERMISSION_DENIED"
}
}
How can I authenticate my request?
Thanks in advance
Pub/Sub does not support the use of API keys as an authentication method (as noted in the documentation). API keys are used for quota attribution for requests. You would have to use one of the alternative authentication methods like OAuth in order to retrieve the schema via a cURL/Get.
If you are logged in via gcloud on an account that has permission to get schemas, you can then get the access token:
gcloud auth application-default print-access-token
Now, you can use that access token in a curl command:
PROJECT=my-project
SCHEMA=my-schema
ACCESS_TOKEN=<token printed out above>
curl -H "Authorization: Bearer $ACCESS_TOKEN" -X GET https://pubsub.googleapis.com/v1/projects/$PROJECT/schemas/$SCHEMA
I have tried everything but somehow unable to generate token or the token that is generated does not work. Please help with what I am doing wrong. I want the token to create an online meeting.
Sharing requests below which I have tried
Generate token with client credentials grant type
REQUEST:
POST 'https://login.microsoftonline.com/CXXXXXXX/oauth2/token'
--header 'Content-Type: application/x-www-form-urlencoded'
--data-urlencode 'password=CXXXXXXX'
--data-urlencode 'grant_type=client_credentials'
--data-urlencode 'scope=OnlineMeetings.ReadWrite'
--data-urlencode 'client_id=CXXXXXXXCXXXXXXX-464c-965a-CXXXXXXXCXXXXXXX'
--data-urlencode 'username=CXXXXXXX#gmail.com'
--data-urlencode 'client_secret=CXXXXXXX6ryCXXXXXXXuV.zu8SmW~D_'
Save the token generated- Using this in https://graph.microsoft.com/v1.0/me/onlineMeetings gives error - Access token validation failure. Invalid audience
Use this token as assertion as follows
POST 'https://login.microsoftonline.com/learn123456789.onmicrosoft.com/oauth2/token'
--header 'Content-Type: application/x-www-form-urlencoded'
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer'
--data-urlencode 'scope=OnlineMeetings.ReadWrite'
--data-urlencode 'client_id=CXXXXXXXCXXXXXXX-464c-965a-CXXXXXXXCXXXXXXX'
--data-urlencode 'client_secret=CXXXXXXX6ryCXXXXXXXuV.zu8SmW~D_'
--data-urlencode 'resource=https://graph.microsoft.com/'
--data-urlencode 'requested_token_use=on_behalf_of'
--data-urlencode 'assertion=tokenFromFirstAPI'
Also tried this api
https://login.microsoftonline.com/common/oauth2/authorize?client_id=CXXXXXXXCXXXXXXX-464c-965a-CXXXXXXXCXXXXXXX&response_type=token&resource=XXXXXXX6-ba00-4fd7-XXXXXXXXX3
Error is
Assertion audience does not match the Client app presenting the assertion. The audience in the assertion was '00000002-0000-0000-c000-000000000000' and the expected audience is 'clientID' or one of the Application Uris of this application with App ID XXX. The downstream client must request a token for the expected audience (the application that made the OBO request) and this application should use that token as the assertion.
No token works in this - https://graph.microsoft.com/v1.0/me/onlineMeetings
Getting - "Access token validation failure. Invalid audience.",
Please help, what am I doing wrong?
Thanks Carl bit it did not work
Have even given all the permissions as suggested above.
ERROR- Bad Request - 400 - 819ms
{ "error": { "code": "AuthenticationError", "message": "Error authenticating with resource", "innerError": { "date": "2020-12-27T09:36:57", "request-id": "4e01eff1-9eb5-42dd-9009-dbdd85aca49a", "client-request-id": "5effa441-d7f6-5ef7-5066-1d7153f39712" } }
As your error message says, your token audience is invalid , because you set the wrong scope when requesting the token. You should set the scope to https://graph.microsoft.com/.default or https://graph.microsoft.com/OnlineMeetings.ReadWrite, in addition, the api call only supports delegated permissions, so you can't use the client credential flow to get the token. For the /me endpoint, the user needs to log in, so you need Use auth code flow to obtain an access token.
Or, there is a simpler method, you can use Graph Explorer to test, you only need to log in to the user and add permissions.
Update:
I noticed that you use 3 methods to get the token.
First of all, for the first method, you are using a v1.0 endpoint and use the client credential flow to obtain the token. What you need to pay attention to is that when you use v1.0 authentication, you cannot use scope, you should use resource. In addition, when you use the client credential flow, you cannot use the v1.0 version , you need to use the beta version, and because the client credential flow is a flow without user login, you cannot call the /me endpoint, you should call the /users endpoint. (Note: When you use the beta version and use the client credential flow, according to the documentation: Administrators must create an application access policy and grant it to a user, authorizing the app configured in the policy to create an online meeting on behalf of that user (user ID specified in the request path).)
The complete request is:
POST https://login.microsoftonline.com/{tenant}/oauth2/token
Content-Type: application/x-www-form-urlencoded
client_id=535fb089-9ff3-47b6-9bfb-xxxxxxxxxx
&resource=https://graph.microsoft.com/
&client_secret=qWgdYAmab0YSkuLxxxxxxx
&grant_type=client_credentials
api call:
https://graph.microsoft.com/beta/users/{userId}/onlineMeetings
For the second method, I noticed that you are using OBO flow, and then you pass in the wrong access token obtained by the first method as an assertion, so the access token you obtained using this flow is definitely not correct. . In addition, if you don't have a back-end API, please do not use this flow. This flow requires you to have a middle-tier API, and it is cumbersome to use.
Your third method is also wrong, your resource should be: https://graph.microsoft.com
To summarize: If you want to use the client credential flow without user login, please refer to my update. If you don't have a backend api, please do not use OBO flow.
IMAGE of ERROR
Error in following URL
"message": "Error authenticating with resource",
https://developer.microsoft.com/en-us/graph/graph-explorer
I wish to use the Google Cloud Platform (GCP) REST API locally, starting with the apps.services.versions.instances.list method.
The route works when I use "Try this API" here, but how would I use this method locally with curl?
"https://appengine.googleapis.com/v1/apps/$APPSID/services/$SERVICESID/versions/$VERSIONSID/instances?key=$YOUR_API_KEY" \
--compressed \
--header 'Accept: application/json' \
--header "Authorization: Bearer $YOUR_ACCESS_TOKEN"
#=>
{
"error": {
"code": 401,
"message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"status": "UNAUTHENTICATED"
}
}
How do I access $YOUR_API_KEY and $YOUR_ACCESS_TOKEN? I have been unable to find either in the official GCP docs.
The fastest way is use Cloud Shell:
List projects to get project id
gcloud projects list
# save you project id
PROJECT_ID="YOURS_PROJECT_ID"
Get ACCESS_TOKEN
ACCESS_TOKEN=$(gcloud auth print-access-token)
Get API_KEY
API_KEY=$(curl -X POST https://apikeys.googleapis.com/v1/projects/$PROJECT_ID/apiKeys?access_token=$ACCESS_TOKEN | jq -r ".currentKey")
Print API_KEY and ACCESS_TOKEN
echo $ACCESS_TOKEN
echo $API_KEY
To run above commands on local machine first you need authenticate using command gcloud auth login and follow instructions.
Alternatively api key could be readed or created from console go to Navigation Menu -> APIs & Services -> Credentials and next click on CREATE CREDENTIALS -> API Key.
By reading the documentation (clicking on question mark next to Credentials) we can read:
[YOUR_API_KEY] - "Include an API Key to identify your project, used to verify enablement and track request quotas."
[YOUR_ACCESS_TOKEN] - "Include an access (bearer) token to identify the user which completed the OAuth flow with your Client ID."
You no longer need an API key. It's a legacy feature of Google APIs, provide only an access token is enough.
In command line you can do this
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" https://....
All the Google Cloud APIs are compliant with access token authentication. Few are still compliant with API keys.
About APIKeys API
This API has been published in beta and now closed. At least the documentation part. I don't know if this API is stable or subject to change. You can create an API key per API like this (very similar to Bartosz Pelikan answer)
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \
-X POST https://apikeys.googleapis.com/v1/projects/PROJECT_ID/apiKeys
As you can see, I reuse the access token authentication mode
The above answers are using an API that isn't publicly available (I reached out to GCP support an confirmed.
I recommend using the CLI tool like so:
gcloud app instances list --service core-api --project my-project-name
docs: https://cloud.google.com/sdk/gcloud/reference/app/instances/list
You'll have to a gcloud auth first and probably set your project.
Using the client_credentials flow in Azure AD, I am unable to retrieve an id_token for my app.
I am experimenting with the Azure AD OAuth/OpenID endpoints, and running into some questions.
I create a simple app with minimal config through the Graph API (a beta endpoint, but still). I have removed all the headers and anonymised in code snippets below:
curl -X POST \
https://graph.microsoft.com/beta/applications \
-d '{
"displayName": "App Name",
"passwordCredentials": [
{
"endDateTime": "2299-12-30T23:00:00Z",
"startDateTime": "2019-02-14T20:19:14.686691Z",
"secretText": "<SOME KEY>",
"displayName": "Client Secret"
}
]
}'
In the response from Azure AD, I get an appId:
{
"#odata.context": "https://graph.microsoft.com/beta/$metadata#applications/$entity",
"id": "<SOME GUID>",
"deletedDateTime": null,
"isFallbackPublicClient": null,
"appId": "<SOME GUID>",
...
This is enough for me to be able to retrieve an access_token from the v1 OAuth endpoint:
curl -X POST \
https://login.microsoftonline.com/tenant_id/oauth2/token \
-d 'client_id=appId&client_secret=secretText&grant_type=client_credentials'
Response:
{
"token_type": "Bearer",
"expires_in": "3600",
"ext_expires_in": "3600",
"expires_on": "1550220412",
"not_before": "1550216512",
"resource": "00000002-0000-0000-c000-000000000000",
"access_token": "<JWT access token>"
}
Since I didn't specify a resource in my call, I get the default Graph API resource.
Now, what I also would like to get is an id_token for my app. I have been able to get these tokens from other OpenID providers. However, the OpenID Connect Core spec. gives me reason to think that id_tokens are for end users only, not apps:
"The ID Token is a security token that contains Claims about the Authentication of an End-User by an Authorization Server when using a Client, and potentially other requested Claims"
(From https://openid.net/specs/openid-connect-core-1_0.html#IDToken)
Adding resource=openid to the POST to the token endpoint above won't work, since openid is a scope, not a resource.
Switching to the v2 endpoints, I get access to a scope parameter. I can obtain an access token from there by setting scope=https://graph.microsoft.com/.default, explicitly requesting the access I got by default through the v1 endpoint.
However, setting the scope to for instance scope=https://graph.microsoft.com/.default openid does not give me an id_token for my app, and the access token looks identical to the previous call.
Trying just scope=openid gives me the following error from Azure AD:
AADSTS70011: The provided request must include a 'scope' input parameter. The provided value for the input parameter 'scope' is not valid. The scope openid is not valid.
All this combined leads me to believe that the OpenID providers I have used and have issued id_tokens through the client_credentials flow are breaking the spec, and that id_tokens can only be obtained for end users (using the authorization_code flow gives me an id_token from Azure AD for myself without any issues).
Is this a correct conclusion, or can I force Azure AD to issue id_tokens to apps as well as end users?
An id_token is issued when a user signs-in. Client credentail flows have no user, so no id_token is issued.
you'd need to use a flow like authorization code grant or openID connect to sign a user in. The response will have a id_token.
You cannot use the client credentials flow to get the id_token for app-only, it only returns the access_token.
i'm trying to use the jhipster tool in order to create a new project with the oauth2 authentication. The project example work fine, i can login with the angularjs interface, but can't understand how can i create a new user and then get the access token via Curl command line for this new user.
Thanks for your help
Step #1: Register the user.
Register a user at http://localhost:8080/#/register and make sure you can log in via the web interface.
Step #2: Obtain an OAuth2 token.
Information required for obtaining an OAuth2 token:
OAuth2 client id (see application.yml)
OAuth2 secret (see application.yml)
The user name and password used to register the new
user.
Required scope/s
Then, obtain an OAuth 2 token from the server:
curl -X POST -vu client:secret http://localhost:8080/oauth/token -H "Accept: application/json" -d "username=username&password=password&grant_type=password&scope=read&client_id=clientid&client_secret=secret"
.. returns something like this:
{"access_token":"7916d326-0f7f-430f-8e32-c5135a121052","token_type":"bearer","refresh_token":"2c69ca58-a657-4780-b5d8-dc965d518e9e","expires_in":1037,"scope":"read"}
Step #3: Use the token in calls to protected resources:
Then, the auth token must be supplied in the header on every call:
curl http://localhost:8080/app/rest/books -H "Authorization: Bearer 7916d326-0f7f-430f-8e32-c5135a121052"