JWT token changes when passing through the GCP API gateway - authentication

I am sending a JWT token in api header. I designed this to pass through GCP api gateway and hit cloudrun service. But when passing through api gateway, the whole JWT token changes every time. There is no effect when I call the cloudrun directly without an api gateway. Any ideas about this?

You have several use cases
If you consider that your Cloud Run requires an authentication, but the access to API Gateway doesn't, the API Gateway is able to generate an identity token, based on the service account in its configuration, and add it to the request forwarded to Cloud Run
If you consider that your Cloud Run requires an authentication and you want to use API Gateway as authentication proxy (for instance, all the users that request the API gateway must be authorized by API gateway (by API key, by FirebaseAuth, by JWT token,...), but the users aren't directly granted on the Cloud RUn service, API Gateway is able to generate an identity token, based on the service account in its configuration, and add it to the request forwarded to Cloud Run
If you consider that your Cloud Run requires an authentication and API Gateway is simply a passthrough to centralise the APIs definition, you can set in your x-google-backend definition, the parameter disable_auth to true. That time, API Gateway won't generate an identity token and won't add it in the forwarded request. The identity token received in entry is forwarded to Cloud RUn (it must be a valid token for Cloud Run)
Note: when API Gateway generate an identity token, the initial authorization token is forwarded in a new header: X-Apigateway-Api-Userinfo

Related

API Gateway with Cognito and LoginWithAmazon

I am creating a REST API on API Gateway and want to use Cognito (User Pool) with LWA for authentication.
Anyone calling the API should be able to use their Amazon account credentials to get access token from Cognito and pass the access token while calling API gateway.
I want to know is it possible for callers to use a curl command or use postman to generate access token via Cognito? I checked that once the access token are generated we can call API gateway using Postman.
Any suggestion/idea on this would be helpful.

difficulties making Cloud Run service the target of an Apps Script project--audience and scopes

I am unable to create an OpenID Connect identity token to send as bearer token for a cloud run request. From the apps script I cannot make a token using (ScriptApp.getIdentityToken()) which has an audience the Google front end will allow through. When I arrange for the script to send a token instead that I've made with gcloud print-identity-token--identical except for the audience--that invocation succeeds.
Note I believe this may the same issue as seen here: Securely calling a Google Cloud Function via a Google Apps Script.
Also google cloud authentication with bearer token via nodejs.
One workaround suggests restructuring the GCP/Apps Script projects. Others mostly use service accounts, and use service account keys. I believe it's possible using IAM and use of google auth for one to produce a usable SA identity token (short term service account credentials) but I can't demonstrate it.
I am working around this currently, but I'd like to understand the essential problem. I think it has something to do with the cloud run service's hosting project's Oauth consent screen, and the inability to add the associated web application client-id as a scope.
In the Cloud Run docs, there is a section about performing authenticated calls to Cloud Run from other services outside GCP. The process would be the following:
Self-sign a service account JWT with the target_audience claim set to the URL of the receiving service.
Exchange the self-signed JWT for a Google-signed ID token, which should have the aud claim set to the above URL.
Include the ID token in an Authorization: Bearer ID_TOKEN header in the request to the service.
Step 1 could be performed as described here while setting the aud claim to the URL of the receiving service. I believe ScriptApp.getIdentityToken() does not set the proper audience to the JWT
For step 2, I believe you should perform a POST request to https://oauth2.googleapis.com/token with the appropriate parameters grant_type and assertion. This is explained in the "Making the access token request" section here
The resulting token should be used in step 3
I just wrote an article on that topic and I provide an easy way based on the service account credential API. Let's have a look on it and we can discuss further if required.

Generate Access Token and validate against IdentityServer4 through Azure API Management

I have an external endpoint which is going to hit the Azure API gateway and that would route it to the backend API which is protected by IdentityServer4 authorization.
I am getting the access token if I hit it through the Postman client with the interactive UI from IdentityServer.
Is there a way I can get the access token required from the Azure API Management to validate against the IdentityServer4 and append it to the header in the request to the backend API?
Yes it is possible to achieve it through custom policy. You can ask your external API-Client/Consumer to paas in credentials in heaser, and then you write a policy inside inbound to can read those user credentials and do a API request (similar to your postman) and get the access token. You can then append the same token and let your request gets forwarded to backend API.
As per your problem statement, this should work. In case not, you might have to explain your scenario with more description/steps.
Here are some of the reference materials for you, I hope it helps.
https://learn.microsoft.com/en-us/azure/api-management/api-management-advanced-policies#SendRequest
https://learn.microsoft.com/en-us/azure/api-management/api-management-sample-send-request
Postman has a luxury of a human user seeing the UI and authorizing API access and IdentityServer4 to issue a token for Postman. There is no such luxury when call is being processed by APIM server, as you could send request for token to IdentityServer4, but who would be presented UI to authorize the action?
The only way is to provision some sort of secret to APIM (header, query, certificate) that would be recognized by IdentityServer4 to allow it issuing tokens for APIM. If such secred is available you could use send-request policy to make a call to IdentityServer4 and obtain required token.
Or make sure that every request to APIM has a token already.

JWT handling with WSO2-AM

we plan to introduce an API management solution and we're currently setting up a proof of concept with WSO2 AM. We want to use the WSO2 API gateway to check whether a certain consumer application is allowed to use an API and to throttle the request rate.
I work on the identity workflow and I wonder how a consuming application can pass a JWT token to the backend service with WSO2-AM in between.
First, this is our current scenario:
Without API gateway
The consuming application gets a JWT token for its carbon user from an identity provider. The JWT contains some claims about the user, e.g. the roles he/she belongs to.
The app calls the service an passes the JWT token in the Authorization HTTP header like: Authorization: Bearer
The service validates the issuer and signature of the JWT and retrieves the claims from it.
So, this is pretty straight forward. Now we put an API gateway in between the application and the service:
With API gateway
The consuming application gets a JWT token for its carbon user from an identity provider.
The consuming application uses OAuth2 to get an access token for the following API calls. We can use the client_credentials grant type and simply pass the the client id and client secret. I haven't yet tried it, but we could possibly use the JWT grant type (see https://docs.wso2.com/display/ISCONNECTORS/Configuring+JWT+Grant+Type) and use the JWT for passing user information to the API gateway.
The API gateway validates the JWT against the public key of the identity provider when using the JWT grant type.
An access token is returned to the app.
The app sends an API request to the gateway and passes the access token in the Authorization HTTP header.
The gateway validates the access token.
The gateway forwards the API request to the service.
And there is my problem: How can the JWT from 1/2. be passed to the service?
There is a documentation for "Passing Enduser Attributes to the Backend Using JWT" (see https://docs.wso2.com/display/AM210/Passing+Enduser+Attributes+to+the+Backend+Using+JWT), but this would introduce a new JWT, issued and signed by WSO2-AM, and I'm not sure, whether this JWT contains all information from the JWT used to create the access token (or even the original JWT).
Another way I could think of is using a custom HTTP header for passing the JWT through the gateway to the service. I cannot use the Authorization header (as we do without the API gateway), because WSO2-AM expects the access token in that header.
Since I'm not happy with either solutions, I want to ask the experts: How would you solve this?
Thanks,
Torsten
The only possibility I can think of is to send the JWT token in a custom Header for the backend service.

Retrieve id_token based on access_token in API

We are current building a collection of back-end ASP.NET Core microservices. These services will not be accessed directly from the front-end application, but rather accessed through an ASP.NET Core API gateway. We are using IdentityServer4 for the OpenID Connect server. I have been able to setup the UseJwtBearerAuthentication middleware to have API gateway validate the JWT bearer token (access_token) against IdentityServer4. I would like to be able to have the API gateway inject the id_token, based on the access_token, into the requests made to the back-end services that may need to know the end-user.
Is there a way to configure the JWT middleware to retrieve the id_token when validation the access_token or do I need to manually call the OpenID Connect server in the API gateway?
You don't use id_tokens at APIs - they are for clients.
If you want to have access to certain identity claims, either include them in the access token (by configuring the ScopeClaims on the resource scope), or use the access token to contact the userinfo endoint which in turn will return the identity claims.
The JWT middleware performs standalone verification, it does not contact the identity server to verify or retrieve anything. You'll have to make an additional call.