hasura / graphql-engine

Blazing fast, instant realtime GraphQL APIs on your DB with fine grained access control, also trigger webhooks on database events.
https://hasura.io
Apache License 2.0
31.17k stars 2.77k forks source link

Error: Could not verify JWT: JWSError JWSInvalidSignature Hasura, Docker and Cognito #3919

Open lucasmachadorj opened 4 years ago

lucasmachadorj commented 4 years ago

I'm developing an application in which I use AWS Cognito as authentication provider. The Hasura Engine is configured in a docker-compose file and it runs in a AWS EC2 machine.

Following this tutorial https://hasura.io/blog/hasura-authentication-explained/#cognito I set HASURA_GRAPHQL_JWT_SECRET as shows below:

HASURA_GRAPHQL_JWT_SECRET: '{"type":"RS256","jwk_url":"https://cognito-idp.<region>.amazonaws.com/<user-pool-id>/.well-known/jwks.json","claims_format":"stringified_json"}'

From the client, I get jwtToken from idToken and put it in authorization header:

{
  Authorization: 'Bearer <jwttoken>'
}

Then follows the error:

nhandled Rejection (Error): Could not verify JWT: JWSError JWSInvalidSignature: {"response":{"errors":[{"extensions":{"path":"$","code":"invalid-jwt"},"message":"Could not verify JWT: JWSError JWSInvalidSignature"}],"status":200}

I don't know if there is any error in my stringified jwks, is it the problem?

As told by @praveenweb in https://github.com/hasura/graphql-engine/issues/3513 I was careful about putting HASURA_GRAPHQL_JWT_SECRET value in a single quote.

tirumaraiselvan commented 4 years ago

@lucasmachadorj Can you check what type of JWT is being generated by Cognito? Is it type: RS256 ? Or something else?

thinknirmal commented 4 years ago

Aren't Cognito JWTs always RS-256?

From here: https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html#amazon-cognito-user-pools-using-tokens-step-2

User pools use an RS256 cryptographic algorithm, which is an RSA signature with SHA-256.

tirumaraiselvan commented 4 years ago

Also, you do not need type key in JWT config if jwk_url is being used since v1.2. So, this issue needs more info. For e.g you can use jwt.io to decode/verify a sample jwt generated by cognito.

xzilja commented 4 years ago

I am getting same error with firebase auth. After following this https://hasura.io/blog/authentication-and-authorization-using-hasura-and-firebase

Use case that is failing for me is following: I have hasura action that triggers firebase cloud function, within that unction I use firebases admin sdk to create new token https://firebase.google.com/docs/auth/admin/create-custom-tokens

I then try to make call to hasura and get same error

   const data = await fetch("https://api.dev/v1/graphql", {
      method: "POST",
      body: JSON.stringify({ query }),
      headers: {
        Authorization: `Bearer ${token}`,
      },
    });

Admin is configured for same project as project id set in hasura HASURA_GRAPHQL_JWT_SECRET I'm not sure if this is related but data here https://firebase.google.com/docs/auth/admin/create-custom-tokens#web looks different to whats in that blog post

productlabs commented 4 years ago

Something that solved for me today is I was copying the access_token too instead of just the id_token in the response. Once I removed the part after &access_token= it worked.

Screen Shot 2020-07-03 at 3 23 37 PM
soulfresh commented 4 years ago

I'm having the same issue with Cognito + Hasura as OP after following the same tutorial directions. I've verified that my token is valid using jwt.io, is RS256, and that the HASURA_GRAPHQL_JWT_SECRET environment variable is set. I'm running Hasura v1.1 so I'm still including the type property in the environment var as described in the tutoral. Removing the type property causes Hasura to return a 503 when making requests.

Any additional debugging suggestions would be greatly appreciated.

soulfresh commented 4 years ago

I was able to resolve my issues by a combination of pressing all the Heroku buttons and regenerating the access token. My guess is that regenerating the access token was what actually fixed my issues. We also upgraded to Hasura 1.3 and removed new line characters from the HASURA_GRAPHQL_JWT_SECRET env var.

jherjati commented 4 years ago

I'm facing the same issue now. If i use cognito for javascript (web app), hasura could verify my JWT, but if i use cognito for mobile app, hasura could not verify the JWT.

Could someone help me please? Is there any different between setting up web app and mobile app?

marksyzm commented 3 years ago

@jherjati Is it that it's not being served via a real secure socket layer? I'm interested to see the outcome here

a-rayene commented 2 years ago

I'm facing the same issue on Hasura 2.4.0; I'm generating the jwt token like this:

export function generateJWT(params: GenerateJWTParams): string { const payload = { "https://hasura.io/jwt/claims": { "x-hasura-allowed-roles": params.allowedRoles, "x-hasura-default-role": params.defaultRole, ...params.otherClaims, }, }; return jwt.sign(payload, HASURA_GRAPHQL_JWT_SECRET.key, JWT_CONFIG); }

but the generated jwt cuases an error GraphQLError(message: Could not verify JWT: JWSError JWSInvalidSignature

ecmonsen commented 2 years ago

I had the same issue as the OP. But after upgrading to Hasura server version 2.7.0 it works.

valentin-harrang commented 1 year ago

Any solution found?

opeah commented 1 year ago

Any update on this? Still have the issue with Firebase Auth and Hasura v2.21.0.

rishi003 commented 1 year ago

I encountered it when I set the sub field of the JWT token as a Number instead of a String.

manuelscurti commented 10 months ago

I am facing the same issue on Hasura v2.0.9. It happens at every server restart and it solves automatically after some time. It seems that it is happening due to hasura not having the right JWK keys at the time of verifying the first incoming JWTs. Thus, when Hasura fetches the JWK keys again from our backend server then it is able to verify JWTs correctly.

amyth commented 10 months ago

Hey, I am using hasura 2.17.0 hosted on an AWS ECS cluster. We currently have hasura configured to work with ADFS using JWTs and everything seems to be working fine. We plan to move from ADFS to cognito and while implementing it, we are stuck with this same issue.

I have cognito a user pool configured and a lambda function to intercept the request to add claims data. It looks like this:

exports.handler = (event, context, callback) => { event.response = { claimsOverrideDetails: { claimsToAddOrOverride: { "https://hasura.io/jwt/claims": JSON.stringify({ "x-hasura-user-id": "testuser", "x-hasura-default-role": "admin", "x-hasura-allowed-roles": ["admin","user"], }), }, }, }; callback(null, event); };

I've used a task and updated the HASURA_GRAPHQL_JWT_SECRET environment variable using the task definition json to include the following and confirmed that it contains the correct jwk_url:

"{ \"type\":\"RS256\", \”claims_format\”:\”stringified_json\”, \"jwk_url\": \"https://cognito-idp.us-east-1.amazonaws.com/us-east-xxxxxxx/.well-known/jwks.json\", \"claims_map\": { \"x-hasura-allowed-roles\": [\"user\", \"admin\"], \"x-hasura-default-role\": \"admin\", \"x-hasura-user-id\": { \"path\": \"$.extension_hasura_id\"} } }"

But I receive the following error:

Could not verify JWT: JWSError JWSInvalidSignature while making queries. Any insights will be really helpful.