2

I have seen similar questions however my use-case seems different. Let me explain.

  1. I have a SINGLE project.
  2. I am using Firebase Authentication in the project
  3. I have created a Node JS based http Cloud Function to different routes.

Using Postman I do a POST request to the Cloud function and use the login route and pass the email and password and get the token in the response.

Using Postman I do a POST request to the Cloud function and use the check route by passing the token from the earlier request and authenticate the token. It works. For this I use the admin.auth().verifyIdToken function of the firebase admin client.

All seems well.

Now, when I set up a Google Cloud Endpoint (on a Google Cloud Run container) in the same project, and:

  1. I have not setup any securities option (as yet) in the Firebase stagger yaml file.

  2. I may a POST request to the Google Cloud Endpoint using login path, I receive the token as before.

  3. But when I make my POST request using the Endpoint to the check path, I receive the "Firebase ID token has incorrect "aud" (audience) claim." error.

I seemed to have tried every option offered by others in these forums. I have created a private key from the firebase console and initialised the firebase admin client with it and yet I get the same error which says: "The claim is supposed to the Project-Id but it takes it to be the Function-name" which is part of the same project.

I have setup my node js function with cors (app.use(cors())) too but same error perpetuates.

I have been at it for the last 4-5 days but do not seem to find out what is the exact problem and why is it not able to accept the admin client function call. Anyone giving me a direction to pursue will be highly appreciated. Thanks.

RmR
  • 1,099
  • 10
  • 22

2 Answers2

2

Yes, ESP and ESPv2 will automatically override the Authorization header with a new token. This is for the use-case where the backend Cloud Run service or Cloud Function require authentication.

You can disable this automatic token override in x-google-backend using disable_auth. https://cloud.google.com/endpoints/docs/openapi/openapi-extensions#jwt_audience_disable_auth

However, your backend can still receive the original token without disabling this feature. From the x-google-backend documentation:

Therefore, if an API client sets the Authorization header, a backend running behind ESPv2 should use the X-Forwarded-Authorization header to retrieve the entire JWT. The backend must verify the JWT in this header, as ESPv2 will not perform verification when authentication methods are not configured.

If you only need the claims from the original token, see Receiving authenticated results in your API.

ESP usually forwards all headers it receives. However, it overrides the original Authorization header when the backend address is specified by x-google-backend in OpenAPI specification or BackendRule in gRPC service configuration. ESP will send the authentication result in the X-Endpoint-API-UserInfo to the backend API. It is recommended to use this header instead of the original Authorization header.

So for your use case, please modify your backend to read either X-Forwarded-Authorization or X-Endpoint-API-UserInfo depending on what fields you need. Do not read the Authorization header if you do not want to set disable_auth.

nareddyt
  • 848
  • 8
  • 16
  • Thanks @nareddyt. But what if I need firebase auth to access the Google Function to which the path redirects the request. In my use-case, the browser client authenticates a firebase user and wants to sent the token with the API gateway request. And the api gateway itself should reject it, if token is invalid or expired. – RmR Feb 12 '20 at 03:20
  • Btw, currently, I am sending the token from the browser client as part of the POST request body and the Google Function is verifying that token. As mentioned, I thought the correct usage of the Google API gateway to filter such authentication at that level. Is it not? – RmR Feb 12 '20 at 03:21
  • I think you're talking about two different things. 1) If you want to write the code in your cloud function to run firebase auth, then you need to set `disable_auth` in ESP so that it doesn't change the token. 2) If you want ESP to do the authentication without you writing any code in your cloud function, you can do that too. That is the intended use case of ESP. See this doc for more info: https://cloud.google.com/endpoints/docs/openapi/authenticating-users-firebase – nareddyt Feb 12 '20 at 03:28
  • Thanks again @nareddyt. It is the later case that I am interested. So when the browser is sending the token to the API gateway, it is giving the above error for which I posed the question. My work around (of authenticating via Google Functions) is a temporary one while I address this issue. In fact, I removed the security declarations from the api yaml file to facilitate this. Thanks – RmR Feb 12 '20 at 05:04
  • Let me clarify the error is thrown by the API gateway – RmR Feb 12 '20 at 05:04
  • Got it. I suggest you post to the [Google Cloud Endpoints group](https://groups.google.com/d/forum/google-cloud-endpoints). Please post your entire service config and the full error you got, we can help you debug it. – nareddyt Feb 12 '20 at 08:06
  • I edited the original answer based on new features. Hopefully this will help. – nareddyt Mar 17 '21 at 16:29
0

My observation has been that the token that gets sent via the request headers get changed by the Google Endpoints server before it is processed by the Google Functions specified in the Path of the Yaml file.

I sent the token in the header as well as the body and found the values to be different by comparing them.

When I used the token sent via the body the firebase-admin client found it to be a valid id, while when I used the token from the request header it gave the above error.

RmR
  • 1,099
  • 10
  • 22