Api Gateway Cognito Authorizer: client token works on AWS ui but not on Postman - authorization

I used the serverless framework to setup some POST apis and then wrote a crude NextJs app to try to authenticate with Cognito and then use the apis protected by the authorizer.
I validated the api and it works without the authorizer. (Tested in Postman)
I am printing to the console the access_token and the id_token received from cognito.
The id_token passes the UI based Authorizer test on aws
My requests both on the front-end app and Postman fail however despite including the Authorization header with the token (tried both tokens).
I also tried to manually enable CORS on the Aws UI but still no luck.
I also looked at this article (https://www.serverless.com/blog/cors-api-gateway-survival-guide/) but no luck and at this point I don't know what to do.
Part of my serverless.yml:
custom:
allowedHeaders:
- Accept
- Content-Type
- Content-Length
- Authorization
- X-Amz-Date
- X-Api-Key
- X-Amz-Security-Token
- X-Amz-User-Agent
- app_user_id
- app_user_name
...
createResource:
handler: api/${name}.handler
description: POST /${name}
events:
- http:
path: api/${name}
method: post
authorizer:
type: COGNITO_USER_POOLS
authorizerId:
Ref: ApiGatewayCognitoAuthorizer
scopes:
- email
cors:
origin: '*'
headers: ${self:custom.allowedHeaders}
reqValidatorName: ${name}RequestValidator
integration: lambda
request:
template:
application/json: ${file(api/resource/mappingTemplates/${name}RequestMappingTemplate.vm)}
passThrough: WHEN_NO_MATCH
...
ApiGatewayCognitoAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
Name: CognitoUserPool-${self:provider.environment.VERSION}
Type: COGNITO_USER_POOLS
IdentitySource: method.request.header.Authorization
RestApiId:
Ref: ApiGatewayRestApi
ProviderARNs:
- ${self:custom.settings.cognitoARN-${env:ENV_NAME}}

I solved the issue after a bunch of attempts. I found this article that is very similar:stackoverflow.com/questions/46345005/… The solution that worked for me was to add 'openid' to the api's oauth scopes instead of just 'email'. Then I tried access_token as opposed to id_token on both Postman and the browser and hallelujah

Related

Xero - Getting 401 Unauthorized for get:/Accounts, scopes added

I am trying to get a list of my accounts using
GET:https://api.xero.com/api.xro/2.0/Accounts with my access token.
The response is 401 / Unauthorized
My app has these scopes:
accounting.transactions
accounting.transactions.read
accounting.settings
accounting.settings.read
accounting.contacts
accounting.contacts.read
accounting.settings.read should be adequate according to the Scopes documentation
I am using the same PHP code used to GET:/Invoices which works fine, with headers:
Accept: application/json
authorization: Bearer $access_token
I am using a Custom Connection, as we have a machine-to-machine setup with no interface.
The App configuration screen, and available scopes are shown here:

How to configure serverless framework HttpApi Authorizer for custom lambda authorizer

In the documentation there is information on how to configure authorizers such as Cognito:
https://www.serverless.com/framework/docs/providers/aws/events/http-api#jwt-authorizers
And here is a copy of it:
httpApi:
authorizers:
someJwtAuthorizer:
identitySource: $request.header.Authorization
issuerUrl: https://cognito-idp.${region}.amazonaws.com/${cognitoPoolId}
Does anyone know how to configure for custom lambda jwt authorizer I have coded myself?
I only achieved it using a previously created JWT Authorizer for httpApi, but must be similar with a custom Lambda Authorizer (never used one)
- httpApi:
method: any
authorizer: # https://github.com/serverless/serverless/issues/7598
# Provide both type and authorizerId
type: COGNITO_USER_POOLS # TOKEN or REQUEST or COGNITO_USER_POOLS, same as AWS Cloudformation documentation
id: <AUTHORIZER ID> # or authorizer name "name: my-lambda"
scopes: # Optional - List of Oauth2 scopes when type is COGNITO_USER_POOLS
- my-resource-server/my-grant-type
path: /{proxy+}
More on this issue here:
AWS HTTP API: Support IAM and Lambda authorizers #8210
feat(AWS HTTP API): Add support for custom Lambda authorizers #9192
Check out the Serverless docs for API Gateway, which show several examples of using custom authorizers.

Can Cloud Endpoints authenticate and revoke requests without hitting my backends?

I have created a small nodejs express Application with two routes:
GET /mypublicurl
GET /myprivateurl
and it's running on GKE. I am triggering it via Cloud Endpoints. For authentication i'm using Auth0, also followed this Tutorial from Google. So my openapi.yaml looks like this:
...
paths:
"/mypublicurl":
get:
description: "See Hello world"
responses:
200:
description: "Hello World"
"/myprivateurl":
get:
description: "See Hello world secure"
responses:
200:
description: "Hello World"
401:
description: "No Auth"
security:
- auth0_jwt: []
securityDefinitions:
auth0_jwt:
authorizationUrl: ...
flow: "implicit"
type: "oauth2"
x-google-issuer: ...
x-google-jwks_uri: ...
x-google-audiences: ...
When i try both routes, i can hit both without Authorization Header.
Also when i put the Bearer Token as Auth Header, of course it still works.
Do i have to make the validation of the JWT token in my backend myself for each route or can cloud endpoints do it and i'm just doing something wrong?

Google SignIn programmatically

I'm creating REST back-end (node.js, although not important for the question), where I authenticate users via Google Sign In.
This is how auth and create user endpoints look like in swagger (I removed all other parts for simplicity):
openapi: 3.0.0
info:
version: 0.1.0
title: XXX API
servers:
- url: 'https://xxx.herokuapp.com/'
- url: 'http://localhost:5000/'
paths:
/auth:
post:
summary: Authenticate user
operationId: authUser
tags:
- auth
parameters:
- name: googleToken
in: query
required: true
schema:
$ref: '#/components/schemas/GoogleToken'
responses:
'200':
$ref: '#/components/responses/LoggedUser'
/users:
post:
summary: Create new user
operationId: createUser
tags:
- users
parameters:
- name: googleToken
in: query
required: true
schema:
$ref: '#/components/schemas/GoogleToken'
responses:
'201':
$ref: '#/components/responses/LoggedUser'
components:
schemas:
UserId:
type: string
GoogleToken:
type: string
User:
type: object
properties:
userId:
$ref: '#/components/schemas/UserId'
responses:
LoggedUser:
description: Successfully logged user
headers:
Auth-Token:
schema:
type: string
example: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJP
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/User'
As you can see, I'm relying on google token for both authentication and user creation. As suggested from the docs, I'm using the google token to authenticate user and retrieve it's google id, email, etc instead of sending around plain googleIds.
To protect my API from unexpected failures during development, I usually create some functional test through services such as Soap UI or Assertible. There you can list your endpoints and what responses you expect by given parameters.
The problem I'm facing is, how to simulate Google Sign In programmatically through my tests? Facebook had functionality to create test user link, but apparently I'm unable to find same solution within Google Docs. Of course I can get one Google Token and hard-code it, but it has rather short expiry time(few hours).
There is one thread within node.js Google library, but without proper solution: github thread.
How do I bypass this problem?
Request a Refresh Token for your test account. Then use that to request an Access Token at the start of each test run. See How do I authorise an app (web or installed) without user intervention?

Use Oauth in Swagger API

I'm building API using swagger and so far I created get/insert/update and delete jobs, and now I'm trying to use Oauth to secure my API
I have used
securityDefinitions:
job_auth:
type: oauth2
authorizationUrl: http://localhost:10010/auth
flow: implicit
scopes:
write:jobs: modify jobs in your account
read:jobs: get your jobs
And in my /get function i used
`paths:
/jobs:
# binds a127 app logic to a route
x-swagger-router-controller: job
get:
description: Returns the job list
# used as the method name of the controller
operationId: getAllJobs
responses:
"200":
description: Success
schema:
$ref: "#/definitions/GetJobsListResponse"
security:
- job_auth:
- read:jobs `
In swagger editor , now it shows
Security
job_auth (OAuth 2.0) Authenticate(Button)
Flow implicit
Authorization URL http://localhost:10010/auth
Scopes
write:jobs modify jobs in your account
read:jobs get your jobs
now i want to access job list using
http://localhost:10010/jobs
but it gives something like this
{
"message": "unknown security handler: job_auth",
"code": "server_error",
"statusCode": 403
}
can anyone help me how to access http://localhost:10010/jobs and set
Authenticate in Oauth properly, I'm new to this