Google Cloud Endpoints - Auth0 - "id_token verification failed: Invalid token signature" - google-cloud-endpoints

I am trying to setup Auth0 with Google Cloud Endpoints.
I followed instructions from
https://cloud.google.com/endpoints/docs/frameworks/python/quickstart-frameworks-python
https://cloud.google.com/endpoints/docs/openapi-configuration
https://cloud.google.com/endpoints/docs/authenticating-users
I want to call "http://10.50.10.31:8080/_ah/api/echo/v1/test/" from my iOS app with an Auth0 authenticated user I already created from the Auth0 iOS SDK.
let url = URL(string: "http://10.50.10.31:8080/_ah/api/echo/v1/test/")!
var request = URLRequest(url: url)
request.addValue("Bearer \(session.token.idToken)", forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
print(data)
print(response)
}
task.resume()
The Swift code works fine. The session.idToken comes from the Auth0 iOS framework.
The file app.yaml is
runtime: python27
api_version: 1
threadsafe: true
env_variables:
# The following values are to be replaced by information from the output of
# 'gcloud service-management deploy swagger.json' command.
ENDPOINTS_SERVICE_NAME: echo-api.endpoints.duskmotion-2016.cloud.goog
ENDPOINTS_SERVICE_VERSION: 2017-02-16r0
builtins:
- appstats: on
- admin_redirect: on
- deferred: on
- remote_api: on
libraries:
- name: jinja2
version: "2.6"
- name: markupsafe
version: "0.15"
- name: pycrypto
version: "2.6.1"
- name: enum
version: "0.9.23"
- name: protorpc
version: "1.0"
- name: pytz
version: "2016.4"
- name: six
version: "1.9.0"
- name: ssl
version: "2.7.11"
- name: werkzeug
version: "0.11.10"
inbound_services:
- warmup
handlers:
- url: /favicon.ico
static_files: application/static/img/favicon.ico
upload: application/static/img/favicon.ico
- url: /robots.txt
static_files: application/static/robots.txt
upload: application/static/robots.txt
- url: /gae_mini_profiler/static
static_dir: lib/gae_mini_profiler/static
- url: /gae_mini_profiler/.*
script: lib.gae_mini_profiler.main.application
- url: /static
static_dir: application/static
- url: /admin/logout
script: run.application.app
secure: always
login: required
- url: /admin/.*
script: run.application.app
secure: always
login: admin
auth_fail_action: redirect
- url: /_ah/warmup
script: run.application.app
secure: always
- url: /_ah/.*
script: run.application.urls.api
- url: .*
script: run.application.app
secure: always
skip_files:
- ^(.*/)?#.*#$
- ^(.*/)?.*~$
- ^(.*/)?.*\.py[co]$
- ^(.*/)?.*/RCS/.*$
- ^(.*/)?.*\(dev\).tmpl
- ^(.*/)?\..*$
- ^(.*/)?setuptools/script \(dev\).tmpl$
The file main.py is
import endpoints
from protorpc import message_types
from protorpc import messages
from protorpc import remote
auth0_issuer = endpoints.Issuer(
issuer='https://duskmotion.auth0.com/',
jwks_uri='https://duskmotion.auth0.com/.well-known/jwks.json')
class EchoRequest(messages.Message):
content = messages.StringField(1)
class EchoResponse(messages.Message):
"""A proto Message that contains a simple string field."""
content = messages.StringField(1)
ECHO_RESOURCE = endpoints.ResourceContainer(
EchoRequest,
n=messages.IntegerField(2, default=1))
#endpoints.api(name='echo', version='v1', issuers={"auth0-jwk" : auth0_issuer})
class EchoApi(remote.Service):
#endpoints.method(
# This method takes a ResourceContainer defined above.
message_types.VoidMessage,
# This method returns an Echo message.
EchoResponse,
path='test',
http_method='GET',
name='echo_test_get')
def echo_test_get(self, request):
# auth = request.headers.get('Authorization', None)
import logging
logging.info(request)
user = endpoints.get_current_user()
content = "Nothing"
if user:
content = "It is working"
import logging
logging.info(content)
if not user:
raise endpoints.UnauthorizedException
return EchoResponse(content=content)
api = endpoints.api_server([EchoApi])
After being generating API file, I manually added the "Security" "x-security" and "securityDefinitions".
The file echov1openapi.json looks like
{
"basePath": "/_ah/api",
"consumes": [
"application/json"
],
"definitions": {
"ApplicationUrlsEchoResponse": {
"properties": {
"content": {
"type": "string"
}
},
"type": "object"
}
},
"host": "echo-api.endpoints.duskmotion-2016.cloud.goog",
"info": {
"title": "echo",
"version": "v1"
},
"paths": {
"/echo/v1/test": {
"get": {
"operationId": "EchoApi_echoTestGet",
"parameters": [],
"responses": {
"200": {
"description": "A successful response",
"schema": {
"$ref": "#/definitions/ApplicationUrlsEchoResponse"
}
}
},
"security": [
{
"auth0_jwk": []
}
]
}
}
},
"produces": [
"application/json"
],
"schemes": [
"http"
],
"x-security": [{
"auth0_jwk": {
"audiences": [
"xxxxxxxxxxxxxxxxxx"
]
}
}],
"securityDefinitions": {
"auth0_jwk": {
"authorizationUrl": "https://duskmotion.auth0.com/authorize",
"flow": "implicit",
"type": "oauth2",
"x-issuer": "https://duskmotion.auth0.com/",
"x-jwks_uri": "https://duskmotion.auth0.com/.well-known/jwks.json"
}
},
"swagger": "2.0"
}
When I run locally on Google App Engine development server, I get
DEBUG 2017-02-16 23:55:25,551 users_id_token.py:198] Checking for id_token.
DEBUG 2017-02-16 23:55:25,551 users_id_token.py:485] Loading certs from https://www.googleapis.com/service_accounts/v1/metadata/raw/federated-signon#system.gserviceaccount.com
DEBUG 2017-02-16 23:55:25,568 users_id_token.py:269] id_token verification failed: Invalid token signature
DEBUG 2017-02-16 23:55:25,569 users_id_token.py:209] Checking for oauth token.
DEBUG 2017-02-16 23:55:25,569 users_id_token.py:340] Fetching token info from https://www.googleapis.com/oauth2/v1/tokeninfo
ERROR 2017-02-16 23:55:25,840 users_id_token.py:349] Token info endpoint returned status 400: Invalid Value
The debug lines 2 and 5 are from myself.
Why do the *.googleapis.com endpoints are getting called instead of my *.auth0.com?
What am I missing in my settings an in the .py file to make it work?

This is a a known issue with Endpoints Frameworks on the development server, and is reported on the project issue tracker: 3rd-party auth does not work with dev-server #55.
See also the related Google Groups thread for an ongoing discussion.

Related

starpi v4 creating entry using api shows cors error and forbidden error

starpi backend and Next.js frontend when called the api to creating entry it shows
module.exports = [
"strapi::errors",
"strapi::security",
{
name: "strapi::cors",
config: {
enabled: true,
// header: "*",
origin: ["http://localhost:3000", "http://localhost:1337"],
},
},
"strapi::poweredBy",
"strapi::logger",
"strapi::query",
"strapi::body",
"strapi::session",
"strapi::favicon",
"strapi::public",
];
I am trying to change this middleware name: "strapi::cors"

symfony nelmio apidoc bundle: areas for yaml-defined method (token refresh from gesdinet)

While upgrading to php8.1 I had to upgrade several modules of my current project, including gesdinet's refresh-token. A ghost method was present in my controller so I could document this api with annotations but it's not possible anymore. I managed to define the refreshtoken api method in nelmio_api_doc.yaml so I can still use it and test it from my sandbox page.
The problem here is that I have 5 areas in my api's documentation (and so, 5 sandbox pages) but the refresh_token method appear in every single one of them instead of only one.
I tried to insert various flavors and syntax of
areas:
- front
in the configuration file but it doesn't seems to work.
Does anyone know how to restrict it the same way it was done with annotations but with the yaml file ? (nelmio's documentation is clearly lacking on the subject)
the "packages/nelmio_api_do.yaml" file
nelmio_api_doc:
documentation:
info:
title: "API documentation"
version: '%version%'
sandbox:
request_format:
method: accept_header
accept_type: application/json
body_format:
formats: [ form, json ]
default_format: form
paths:
/api/front/token/refresh:
post:
tags:
- Authentication
summary: Refresh token mechanism
parameters:
refresh_token:
in: formData
name: refresh_token
type: string
responses:
'200':
description: OK
schema:
type: object
properties:
token:
type: string
refresh_token:
type: string
'401':
description: An authentication exception occurred.
security: [ ]
areas:
default:
path_patterns: [ ^/api/test/default ]
front:
path_patterns: [ ^/api/front ]
in advance thanks for your ideas.
(php 8.1 / symfony 5.4 / nelmio 3.10.1)
Nevermind guys, I eventually found the solution.
I was trying to follow what I saw for defining paths in the yaml file but while I tried to insert it in
nelmio_api_doc->documentation->paths->[the_method_path] (which works)
the right way to do this and condition the method to an area is:
nelmio_api_doc->documentation->areas->[your_area_name]->paths->[the_method_path]
so now the file looks like:
nelmio_api_doc:
documentation:
info:
title: "API documentation"
version: '%version%'
sandbox:
request_format:
method: accept_header
accept_type: application/json
body_format:
formats: [ form, json ]
default_format: form
areas:
default:
path_patterns: [ ^/api/test/default ]
front:
path_patterns: [ ^/api/front ]
paths:
/api/front/token/refresh:
post:
tags:
- Authentication
summary: Refresh token mechanism
parameters:
refresh_token:
in: formData
name: refresh_token
type: string
responses:
'200':
description: OK
schema:
type: object
properties:
token:
type: string
refresh_token:
type: string
'401':
description: An authentication exception occurred.
security: [ ]
This work for me
nelmio_api_doc:
areas:
oauth:
path_patterns:
- /oauth
documentation:
basePath: /
info:
title: oauth api
description: oauth documentation
paths:
/oauth/v2/token:
post:
tags:
- Authentication
produces:
- application/json
parameters:
- name: client_id
in: formData
required: true
type: string
- name: username
in: formData
required: true
type: string
example: 'test#test.fr'
- name: password
in: formData
required: true
type: string
example: 'password'
- name: grant_type
in: formData
required: true
type: string
example: 'password'
responses:
200:
description: Login successful
schema:
type: object
properties:
access_token:
type: string
expires_in:
type: integer
token_type:
type: string
example: 'bearer'
scope:
type: string
example: null
refresh_token:
type: string
403:
description: Login failed
schema:
type: array
properties:
error:
type: string
error_description:
type: string
default:
path_patterns:
- /address
documentation:
basePath: /
info:
title: default API
description: default API documentation
paths:
/address:
get:
tags:
- address
summary: OK - List address types
produces:
- application/json
parameters:
- name: access_token
type: string
in: query
required: true
description: API access token
responses:
200:
description: Returned when successful
schema:
items:
$ref: "#definitions/AddressEntity"
type: array
examples:
application/json:
data:
- type: adress type
id: M
attributes:
id: M
label: Main Address
401:
description: Bad access token

Next-Auth with FaunaDB Dev Get Session Error

I've set up Next-Auth on my NextJS project to use FaunaDB. I've managed to get it working on my production environment, however, it seems to not be working on my development environment, which is using the Fauna Dev docker container rather than the cloud-based database.
Whenever I run the dev server, I get the following error log;
https://next-auth.js.org/errors#fauna__get_session_error [NotFound: instance not found] {
description: 'Set not found.',
requestResult: RequestResult {
method: 'POST',
path: '',
query: null,
requestRaw: '{"get":{"match":{"index":"session_by_token"},"terms":"86b962d600c3f53d41d5140de6daed654a473e670a99943d7fb301a4fc86357e"}}',
requestContent: Expr { raw: [Object] },
responseRaw: '{"errors":[{"position":[],"code":"instance not found","description":"Set not found."}]}',
responseContent: { errors: [Array] },
statusCode: 404,
responseHeaders: [Object: null prototype] {
':status': 404,
'x-txn-time': '1630008523944000',
'x-compute-ops': '1',
'x-read-ops': '0',
'x-byte-read-ops': '0',
'x-byte-write-ops': '0',
'x-write-ops': '0',
'x-query-time': '703',
'x-query-bytes-in': '121',
'x-query-bytes-out': '87',
'x-storage-bytes-read': '0',
'x-storage-bytes-write': '0',
'x-txn-retries': '0',
'x-faunadb-build': '21.08.00-4d315fa',
'content-length': '87',
'content-type': 'application/json;charset=utf-8'
},
startTime: 1630008521471,
endTime: 1630008522280
}
}
I've followed the guide to set this up and continue to get the same error. I've removed and recreated the fauna docker container several times, still the same error. I also have some data that I can access in the local Fauna Dev database, so that seems to be set up fine. Also if I change my .env.local environment variables to the ones I use on production, it all works fine, but of course is then using the cloud database.
Here's a comparison of my production and local variables, with private keys removed;
# .env.local
GOOGLE_ID=<removed>
GOOGLE_SECRET=<removed>
NEXT_PUBLIC_FAUNA_ADMIN_KEY=<removed>
NEXT_PUBLIC_FAUNA_DOMAIN=localhost
NEXT_PUBLIC_FAUNA_GRAPHQL_ENDPOINT=http://localhost:8084/graphql
NEXT_PUBLIC_FAUNA_PORT=8443
NEXT_PUBLIC_FAUNA_SCHEME=http
NEXTAUTH_URL=http://localhost:3000
# production env
GOOGLE_ID=<removed, identical to local>
GOOGLE_SECRET=<removed, identical to local>
NEXT_PUBLIC_FAUNA_ADMIN_KEY=<removed, different to local>
NEXT_PUBLIC_FAUNA_DOMAIN=db.eu.fauna.com
NEXT_PUBLIC_FAUNA_GRAPHQL_ENDPOINT=https://graphql.eu.fauna.com/graphql
NEXT_PUBLIC_FAUNA_SCHEME=https
NEXTAUTH_URL=https://dnd-compendium-five.vercel.app
And for good measure, here's my [...nextauth].ts file;
import NextAuth from "next-auth";
import Providers from "next-auth/providers";
import * as Fauna from "faunadb";
import { FaunaAdapter } from "#next-auth/fauna-adapter";
const isProduction = process.env.NODE_ENV === "production";
const client = new Fauna.Client({
secret: process.env.NEXT_PUBLIC_FAUNA_ADMIN_KEY,
scheme: process.env.NEXT_PUBLIC_FAUNA_SCHEME === "https" ? "https" : "http",
domain: process.env.NEXT_PUBLIC_FAUNA_DOMAIN,
...(isProduction ? {} : { port: +process.env.NEXT_PUBLIC_FAUNA_PORT }),
});
export default NextAuth({
// Configure one or more authentication providers
providers: [
Providers.Google({
clientId: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_SECRET,
}),
// ...add more providers here
],
adapter: FaunaAdapter({ faunaClient: client }),
});
Update
Here's several documents from the production Fauna database, with personal info removed;
# accounts collection document
{
"ref": Ref(Collection("accounts"), "307944413618766018"),
"ts": 1629937528150000,
"data": {
"userId": "307944413481402562",
"providerId": "google",
"providerType": "oauth",
"providerAccountId": "110736403335097897627",
"accessToken": "ya29.a0ARrdaM_n4D6gDvzs8Mxs851r70Xs5v5HROSdcDM0HJoMP1XFhAPhFbmh46e4bfHzTbVYOhoc2W7N_0IHpV3yEW5a__Nzy8NrxWU3ns-KlxIm_oTXRVW0RyitT26uXtTq-45k6OTjakjHsinYpnof4qdXcICg",
"createdAt": Time("2021-08-26T00:25:28.101705Z"),
"updatedAt": Time("2021-08-26T00:25:28.101705Z")
}
}
# sessions collection document
{
"ref": Ref(Collection("sessions"), "308011284890124486"),
"ts": 1630001301580000,
"data": {
"userId": "307946306265940166",
"expires": Time("2021-09-25T18:08:21.521Z"),
"sessionToken": "997b45bb432cfbc05901e9a92ae9d1ac36637246277ac05ad915fb00b8fc9130",
"accessToken": "9dbec0113a46bc6a0768e1a5b7baafac65a1fb0a29568bc11562cd58ad97d5b9",
"createdAt": Time("2021-08-26T18:08:21.517447Z"),
"updatedAt": Time("2021-08-26T18:08:21.517447Z")
}
}
# users collection document
{
"ref": Ref(Collection("users"), "307946306265940166"),
"ts": 1629939333135000,
"data": {
"name": <string removed>,
"email": <string removed>,
"image": <url string removed>,
"createdAt": Time("2021-08-26T00:55:33.075553Z"),
"updatedAt": Time("2021-08-26T00:55:33.075553Z")
}
}
Which verisons of next-auth and the adapter are you using? They recently released a v4 beta and matching adapter beta's. Maybe you'll have more luck with those newer releases 👍

Symfony: monolog formatter not being applied to all log messages

I want to have all my logs stored as json so I'm using the monolog.formatter.json like this
monolog:
handlers:
main:
type: stream
path: "php://stderr"
level: info
channels: ["!event"]
formatter: 'monolog.formatter.json
However i'm still seeing in the logs lines like this
[2021-04-16T09:29:17.946886+00:00] security.DEBUG: Checking for authenticator support. {
"firewall_name": "endusers",
"authenticators": 2
} {
"request_id": "21b36d09-8cc0-466c-b835-1bc8fb05bf47"
}
(but i correctly have other logs formatted like this
{
"message": "......",
"context": [
1401
],
"level": 100,
"level_name": "DEBUG",
"channel": "doctrine",
"datetime": "2021-04-16T09:29:18.047739+00:00",
"extra": {
"request_id": "21b36d09-8cc0-466c-b835-1bc8fb05bf47"
}
}
which makes me think that my configuration is correct but somehow some logs are not going through my handler
Is there something I'm missing ?
(I'm using symfony 5.2 and monologbundle 3.7.0 )

Api gateway get item dynamodb configuration

Hi i need get an item from dynamodb through api gateway and i configure the resources like this:
i configure the integration method like the next picture:
and the mapping template is like this:
but when i test apigateway launch this error
Execution failed due to configuration error:
No match for output mapping and no default output mapping configured.
Endpoint Response Status Code: 200
Gateway response type: API_CONFIGURATION_ERROR with status code: 500
I followed these two tutorials and performed get on my dynamoDB table.
My table has primary key name "pk".
Tutorials: Video & Blog
If i write my dynamo request body like yours it does not fetch any record
{
"TableName": "apiG",
"Key": {
"pk": {
"S": "key1"
}
}
}
But if I form my request like
{
"TableName": "apiG",
"PrimaryKey": "pk",
"KeyConditionExpression": "pk = :v1",
"ExpressionAttributeValues": {
":v1": {
"S": "key1"
}
}
}
I get the desired response from dynamoDB.
Your error looks like you have some mix up in your integration response and method response. In the simplest form, keep your method response as default i.e. "HTTP Status: 200 Models: application/json => Empty" and leave your integration response as API Gateway console creates it for you.
This will make sure your DynamoDB output is sent without modification to your browser/output.
I transformed my dynamo output using following mapping template in integration response.
#set($inputRoot = $input.path('$'))
{
"content": [
#foreach($elem in $inputRoot.Items) {
"key": "$elem.pk.S",
"value": "$elem.pv.S"
}#if($foreach.hasNext),#end
#end
]
}
and it produced following output.
{
"content": [
{
"key": "key1",
"value": "val1"
}
]
}
P.S. i had a dynamo table named 'apiG' with primaryKey 'pk' and following the exported swagger from my experiment. Hope it helps.
openapi: "3.0.1"
info:
title: "dynamoProxy"
version: "2020-05-01T06:45:38Z"
servers:
- url: "https://aaaaaaaaaa.execute-api.us-east-2.amazonaws.com/{basePath}"
variables:
basePath:
default: "/test"
paths:
/db:
get:
responses:
200:
description: "200 response"
content:
application/json:
schema:
$ref: "#/components/schemas/Empty"
x-amazon-apigateway-integration:
credentials: "arn:aws:iam::111111111111:role/apiGddbRole"
uri: "arn:aws:apigateway:us-east-2:dynamodb:action/Query"
responses:
default:
statusCode: "200"
responseTemplates:
application/json: "#set($inputRoot = $input.path('$'))\n{\n \"content\"\
: [\n #foreach($elem in $inputRoot.Items) {\n \"\
key\": \"$elem.pk.S\",\n \"value\": \"$elem.pv.S\"\n \
\ }#if($foreach.hasNext),#end\n\t#end\n ]\n}"
passthroughBehavior: "when_no_templates"
httpMethod: "POST"
requestTemplates:
application/json: "{\n \"TableName\": \"apiG\",\n \"PrimaryKey\":\
\ \"pk\",\n \"KeyConditionExpression\": \"pk = :v1\",\n \"ExpressionAttributeValues\"\
: {\n \":v1\": {\n \"S\": \"key1\"\n }\n }\n\
}"
type: "aws"
components:
schemas:
Empty:
title: "Empty Schema"
type: "object"
Cheers!

Resources