My purpose is to secure my backend, which is deployed as GCP App Engine, with an API-Gateway, provided by Google, to only let Firebase authenticated users have access to it.
I set everything up, as stated in the documents:
API-Gateway config:
{
"swagger": "2.0",
"info": {
"title": "PROJECT_NAME",
"version": "1.0"
},
"securityDefinitions": {
"firebase": {
"authorizationUrl": "",
"flow": "implicit",
"type": "oauth2",
"x-google-issuer": "https://securetoken.google.com/PROJECT_ID",
"x-google-jwks_uri": "https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com",
"x-google-audiences": "PROJECT_ID"
}
},
"security": [
{
"firebase": [ ]
}
],
"paths": {
"/hello-spring": {
"get": {
"produces": [
"application/json"
],
"operationId": "helloSpring",
"parameters": [],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
}
},
"x-google-backend": {
"address": "https://URI-TO-APP-ENGINE-SERVICE",
"path_translation": "APPEND_PATH_TO_ADDRESS"
"jwt_audience": "API_CREDENTIALS_FROM_IAP_APP_ENGINE_APP"
}
}
}
},
"definitions": {
"User": {
"properties": {
"creationTimestamp": {
"format": "date-time",
"type": "string"
},
"id": {
"format": "int32",
"type": "integer"
},
"name": {
"type": "string"
},
"updateTimestamp": {
"format": "date-time",
"type": "string"
},
"uuid": {
"type": "string"
}
},
"type": "object"
}
},
"x-components": {}
}
When I send a request - without a jwt token - to this api-gateways url, it correctly responds with
{
"message": "Jwt is missing",
"code": 401
}
Firebase jwt
"Default" firebase backend is used, no custom tokens are created. Firebase is used to create the JWT token. From the client following code snippet is used to receive a valid JWT:
final FirebaseAuth _auth = FirebaseAuth.instance;
....
final GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn();
final GoogleSignInAuthentication googleSignInAuthentication = await googleSignInAccount.authentication;
final AuthCredential credential = GoogleAuthProvider.credential(
accessToken: googleSignInAuthentication.accessToken,
idToken: googleSignInAuthentication.idToken,
);
final UserCredential authResult = await _auth.signInWithCredential(credential);
final String token = await _auth.currentUser.getIdToken();
But as soon as I add the JWT (final String token in code above), which is created by a firebase client app and add it to the request header with
Authorization: Bearer TOKEN_CODE
gateway responds with
{
"code": 401,
"message": "Jwt verification fails"
}
The most detailed LOG I can see in GCP is:
response_code_detail: jwt_authn_access_denied{Jwt_verification_fails}
I also created a service account linked to this API-Gateway with following roles:
- roles/appengine.appViewer
- roles/iam.serviceAccountUser
- roles/run.invoker
- roles/apigateway.viewer
But still, the same error: "401 - Jwt verification fails". What am I missing,how can I see more details about this issue in GCP and what could be a solution?