2
votes

I am trying my hands on configuring Endpoints on Cloud Functions by following the article.

Have performed the following steps:

1) Create a Google Cloud Platform (GCP) project, and deployed the following Cloud Function.

export const TestPost = (async (request: any, response: any) => {
    response.send('Record created.');
});

using following command

gcloud functions deploy TestPost --runtime nodejs10 --trigger-http --region=asia-east2

Function is working fine till here.

2) Deploy the ESP container to Cloud Run using following command

gcloud config set run/region us-central1

gcloud beta run deploy CLOUD_RUN_SERVICE_NAME \
    --image="gcr.io/endpoints-release/endpoints-runtime-serverless:1.30.0" \
    --allow-unauthenticated \
    --project=ESP_PROJECT_ID

ESP container is successfully deployed as well.

3) Create an OpenAPI document that describes the API, and configure the routes to the Cloud Functions.

swagger: '2.0'
info:
    title: Cloud Endpoints + GCF
    description: Sample API on Cloud Endpoints with a Google Cloud Functions backend
    version: 1.0.0
host: HOST
schemes:
- https
produces:
    - application/json
paths:
    /Test:
      get:
        summary: Do something
        operationId: Test
        x-google-backend:
            address: https://REGION-FUNCTIONS_PROJECT_ID.cloudfunctions.net/Test
        responses:
            '200':
                description: A successful response
                schema:
                    type: string

4) Deploy the OpenAPI document using following command

gcloud endpoints services deploy swagger.yaml

5) Configure ESP so it can find the configuration for the Endpoints service.

gcloud beta run configurations update \
   --service CLOUD_RUN_SERVICE_NAME  \
   --set-env-vars ENDPOINTS_SERVICE_NAME=YOUR_SERVICE_NAME \
   --project ESP_PROJECT_ID

gcloud alpha functions add-iam-policy-binding FUNCTION_NAME \
    --member "serviceAccount:[email protected]" \
    --role "roles/iam.cloudfunctions.invoker" \
    --project FUNCTIONS_PROJECT_ID

This is done successfully

6) Sending requests to the API

Works absolutely fine.

Now I wanted to Implement authentication so I made following changes to OpenAPI document

swagger: '2.0'
info:
    title: Cloud Endpoints + GCF
    description: Sample API on Cloud Endpoints with a Google Cloud Functions backend
    version: 1.0.0
host: HOST
schemes:
- https
produces:
    - application/json
security:
    - client-App-1: [read, write]
paths:
    /Test:
      get:
        summary: Do something
        operationId: Test
        x-google-backend:
            address: https://REGION-FUNCTIONS_PROJECT_ID.cloudfunctions.net/Test
        responses:
            '200':
                description: A successful response
                schema:
                    type: string
securityDefinitions:
    client-App-1:
        authorizationUrl: ""
        flow: "implicit"
        type: "oauth2"
        scopes:
            read: Grants read access
            write: Grants write access
        x-google-issuer: [email protected]
        x-google-jwks_uri: https://www.googleapis.com/robot/v1/metadata/x509/[email protected]

I created a service account using following command.

gcloud iam service-accounts create SERVICE_ACCOUNT_NAME --display-name DISPLAY_NAME

Granted Token Creator role to service account using following

gcloud projects add-iam-policy-binding PROJECT_ID --member serviceAccount:SERVICE_ACCOUNT_EMAIL --role roles/iam.serviceAccountTokenCreator

Redeploy the OpenAPI document

gcloud endpoints services deploy swagger.yaml

Now when I test the API I get following error

{
    "code": 16,
    "message": "JWT validation failed: BAD_FORMAT",
    "details": [
        {
            "@type": "type.googleapis.com/google.rpc.DebugInfo",
            "stackEntries": [],
            "detail": "auth"
        }
    ] }

I am passing the access token generated via gcloud into the request using BearerToken

cmd for generating access token is gcloud auth application-default print-access-token

Can some one point out what the issue here. Thanks...

Edit#1: I am using Postman to connect to my API's

After using the following command I am getting a different error.

Command:

gcloud auth print-identity-token SERVICE_ACCOUNT_EMAIL

Error:

{
    "code": 16,
    "message": "JWT validation failed: Issuer not allowed",
    "details": [
        {
            "@type": "type.googleapis.com/google.rpc.DebugInfo",
            "stackEntries": [],
            "detail": "auth"
        }
    ]
}
2
I think the problem is with the following but I am not sure what should be here x-google-issuer & x-google-audiencesniklodeon
You left out the one section that matters. The code that is causing the error. Edit your question and show how you are using the token generated by gcloud.John Hanley
@John Hanley, I found the issue. I was generating an access token and was using that to access the api. What u need is a signed jwt token. I will try to generate one and c if that works r not.niklodeon
BTW I was accessing API via Postman...niklodeon
I might be wrong, I am using my memory here. I don't think you want an Access Token, I think you want an Identity Token. cloud.google.com/sdk/gcloud/reference/auth/print-identity-tokenJohn Hanley

2 Answers

2
votes

For ESP, you should use jwt-token, or identity token. not access token. Please check this out.

1
votes

Finally I manager to solve the issue.

Two things were wrong.

1) The format of the raw JWT token, it should be as following

{
    "iss": SERVICE_ACCOUNT_EMAIL,
    "iat": 1560497345,
    "aud": ANYTHING_WHICH_IS_SAME_AS_IN_OPENAPI_YAML_FILE,
    "exp": 1560500945,
    "sub": SERVICE_ACCOUNT_EMAIL
}

and then we need to generate a signed JWT token using following command

gcloud beta iam service-accounts sign-jwt --iam-account SERVICE_ACCOUNT_EMAIL raw-jwt.json signed-jwt.json

2) The security definition in the YAML file should be like following

securityDefinitions:
  client-App-1:
    authorizationUrl: ""
    flow: "implicit"
    type: "oauth2"
    scopes:
      read: Grants read access
      write: Grants write access
    x-google-issuer: SERVICE_ACCOUNT_EMAIL 
    x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/SERVICE_ACCOUNT_EMAIL
    x-google-audiences: ANYTHING_BUT_SAME_AS_IN_RAW_JWT_TOKEN