Manually verifying a JWT
-
I have an access token that is signed by a HS256 signing key. When I go to my rails backend and use the JWT library to decode it and verify it is a valid token signed by FusionAuth it is return Signature Verification Error. Am I doing something wrong?
This is my rails code to decode and verify that the JWT is valid:
JWT.decode(access_token, signing_key, true)
This is my default signing key (Yes I know it is insecure to share this, but it's a dev server not production and I will change it after this):
(Signing key in text):
1c8e490a-4972-7d73-8935-06621a0a6441
And here is an example JWT that was issued:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjllZDRjNjc1NCJ9.eyJhdWQiOiI5MzgwZDJjNi1jNDM1LTRlZWMtYTg5Ny05ZWM5ZDA4NGJjZTgiLCJleHAiOjE1OTQ0ODk5NTMsImlhdCI6MTU5NDQ4NjM1MywiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiIxMzUyOWVkZi05NjFlLTRkM2EtODE3Ny1hMmYxN2NmNTU0YjEiLCJhdXRoZW50aWNhdGlvblR5cGUiOiJQQVNTV09SRCIsImVtYWlsIjoibXNyYWdoZWJAdWNpLmVkdSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJyb2xlcyI6WyJTZXJ2YW50Il0sImFwcGxpY2F0aW9uSWQiOiI5MzgwZDJjNi1jNDM1LTRlZWMtYTg5Ny05ZWM5ZDA4NGJjZTgiLCJwZXJzb25faWQiOjF9.aKajyZmIWe0d0ijoV2oTpxVUeQpOieaV5C80SoLqCrA
I don't know how to further debug this. Any help appreciated, thank you.
-
Hiya,
Here's an example library of decoding JWTs: https://github.com/FusionAuth/fusionauth-example-ruby-jwt
Code based on this seems to work with your payload:
require 'jwt' hmac_secret = '1c8e490a-4972-7d73-8935-06621a0a6441' exp = Time.now.to_i + (5*60) iat = Time.now.to_i + (0*60) payload = { "aud": "9380d2c6-c435-4eec-a897-9ec9d084bce8", "exp": exp, "iat": iat, "iss": "acme.com", "sub": "13529edf-961e-4d3a-8177-a2f17cf554b1", "authenticationType": "PASSWORD", "email": "msragheb@uci.edu", "email_verified": true, "roles": [ "Servant" ], "applicationId": "9380d2c6-c435-4eec-a897-9ec9d084bce8", "person_id": 1 } token = JWT.encode payload, hmac_secret, 'HS256', {"typ": "JWT", "kid": "abc"} puts token decoded_token = JWT.decode token, hmac_secret, true, { algorithm: 'HS256' } puts decoded_token
Here's similar code which just takes a JWT and decodes it:
require 'jwt' # the todo API hmac_secret = '1c8e490a-4972-7d73-8935-06621a0a6441' token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjllZDRjNjc1NCJ9.eyJhdWQiOiI5MzgwZDJjNi1jNDM1LTRlZWMtYTg5Ny05ZWM5ZDA4NGJjZTgiLCJleHAiOjE1OTQ0ODk5NTMsImlhdCI6MTU5NDQ4NjM1MywiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiIxMzUyOWVkZi05NjFlLTRkM2EtODE3Ny1hMmYxN2NmNTU0YjEiLCJhdXRoZW50aWNhdGlvblR5cGUiOiJQQVNTV09SRCIsImVtYWlsIjoibXNyYWdoZWJAdWNpLmVkdSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJyb2xlcyI6WyJTZXJ2YW50Il0sImFwcGxpY2F0aW9uSWQiOiI5MzgwZDJjNi1jNDM1LTRlZWMtYTg5Ny05ZWM5ZDA4NGJjZTgiLCJwZXJzb25faWQiOjF9.aKajyZmIWe0d0ijoV2oTpxVUeQpOieaV5C80SoLqCrA' puts token decoded_token = JWT.decode token, hmac_secret, true, { algorithm: 'HS256' } puts decoded_token
Right now of course the JWT you provided won't be valid because it expired. Can you generate a JWT good for 30 days and share that here? Or try to use the above code to decode it?
I'd also make sure that the server has the correct time on it and that the access token is just the JWT and doesn't include
Bearer
. -
@dan said in Manually verifying a JWT:
hmac_secret = '1c8e490a-4972-7d73-8935-06621a0a6441'
token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjllZDRjNjc1NCJ9.eyJhdWQiOiI5MzgwZDJjNi1jNDM1LTRlZWMtYTg5Ny05ZWM5ZDA4NGJjZTgiLCJleHAiOjE1OTQ0ODk5NTMsImlhdCI6MTU5NDQ4NjM1MywiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiIxMzUyOWVkZi05NjFlLTRkM2EtODE3Ny1hMmYxN2NmNTU0YjEiLCJhdXRoZW50aWNhdGlvblR5cGUiOiJQQVNTV09SRCIsImVtYWlsIjoibXNyYWdoZWJAdWNpLmVkdSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJyb2xlcyI6WyJTZXJ2YW50Il0sImFwcGxpY2F0aW9uSWQiOiI5MzgwZDJjNi1jNDM1LTRlZWMtYTg5Ny05ZWM5ZDA4NGJjZTgiLCJwZXJzb25faWQiOjF9.aKajyZmIWe0d0ijoV2oTpxVUeQpOieaV5C80SoLqCrA'
puts token
decoded_token = JWT.decode token, hmac_secret, true, { algorithm: 'HS256' }
puts decoded_token
Thanks for the response. Here's one that was just generated and shouldn't be expired:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjllZDRjNjc1NCJ9.eyJhdWQiOiI5MzgwZDJjNi1jNDM1LTRlZWMtYTg5Ny05ZWM5ZDA4NGJjZTgiLCJleHAiOjE1OTQ1MDIwMTQsImlhdCI6MTU5NDQ5ODQxNCwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiIxMzUyOWVkZi05NjFlLTRkM2EtODE3Ny1hMmYxN2NmNTU0YjEiLCJhdXRoZW50aWNhdGlvblR5cGUiOiJQQVNTV09SRCIsImVtYWlsIjoibXNyYWdoZWJAdWNpLmVkdSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJhcHBsaWNhdGlvbklkIjoiOTM4MGQyYzYtYzQzNS00ZWVjLWE4OTctOWVjOWQwODRiY2U4Iiwicm9sZXMiOlsiU2VydmFudCJdLCJwZXJzb25faWQiOjF9.Xf_LYuqhxC1mskoEtKTJogqA_x3PKJlpwkXgRokgI2I
I tried this following code like yours with the new token and it gives me signature error:
hmac_secret = '1c8e490a-4972-7d73-8935-06621a0a6441' token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjllZDRjNjc1NCJ9.eyJhdWQiOiI5MzgwZDJjNi1jNDM1LTRlZWMtYTg5Ny05ZWM5ZDA4NGJjZTgiLCJleHAiOjE1OTQ1MDIwMTQsImlhdCI6MTU5NDQ5ODQxNCwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiIxMzUyOWVkZi05NjFlLTRkM2EtODE3Ny1hMmYxN2NmNTU0YjEiLCJhdXRoZW50aWNhdGlvblR5cGUiOiJQQVNTV09SRCIsImVtYWlsIjoibXNyYWdoZWJAdWNpLmVkdSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJhcHBsaWNhdGlvbklkIjoiOTM4MGQyYzYtYzQzNS00ZWVjLWE4OTctOWVjOWQwODRiY2U4Iiwicm9sZXMiOlsiU2VydmFudCJdLCJwZXJzb25faWQiOjF9.Xf_LYuqhxC1mskoEtKTJogqA_x3PKJlpwkXgRokgI2I' puts token decoded_token = JWT.decode token, hmac_secret, true, { algorithm: 'HS256' } puts decoded_token
-
I don't think it's an issue with server time. I can't verify the signature on jwt.io when using my secret and token.
Here is the long lasting token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjllZDRjNjc1NCJ9.eyJhdWQiOiI5MzgwZDJjNi1jNDM1LTRlZWMtYTg5Ny05ZWM5ZDA4NGJjZTgiLCJleHAiOjE1OTQ1ODU2ODYsImlhdCI6MTU5NDQ5OTI4NiwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiIxMzUyOWVkZi05NjFlLTRkM2EtODE3Ny1hMmYxN2NmNTU0YjEiLCJhdXRoZW50aWNhdGlvblR5cGUiOiJQQVNTV09SRCIsImVtYWlsIjoibXNyYWdoZWJAdWNpLmVkdSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJhcHBsaWNhdGlvbklkIjoiOTM4MGQyYzYtYzQzNS00ZWVjLWE4OTctOWVjOWQwODRiY2U4Iiwicm9sZXMiOlsiU2VydmFudCJdLCJwZXJzb25faWQiOjF9.GQNEPj3GJe5ejQFg3YVmBmVEbMUlmQLSUuyPe2bTUXk
-
Something is very wrong. I don't know if this is something anybody else is facing, but I changed to a RS256 key and used the public key on jwt.io and it is still invalid. I cannot validate a JWT outside of /api/jwt/validate. This is a really big deal to me to be able to do something as simple as validating. Please let me know if I am in error, but if I can't get this to work I cannot continue using fusionauth and that's a big bummer to me as I had high hopes for this service.
-
Hmmm. I'll take a look on Monday.
-
Hiya,
I was able to successfully decode a JWT. From reviewing this thread, I think maybe the issue is that you are using the wrong secret. It seems like you might have accidentally been using the id of the signing key
'1c8e490a-4972-7d73-8935-06621a0a6441'
instead of the actual secret key.Here's how I found my secret key:
- go to settings
- go to keymaster
- click on the green magnifying glass icon to view the default key
- click on
click here
to see the secret.
My secret looked something like this:
n0EfufcUAuYM6199G3ffRp+YUVMPodabtlI/wT8oBYc=
.Can you try validating your JWT with the secret found through those steps and let me know how it goes?
-
Thank you so much Dan, that was exactly the issue. I successfully verified a token with that secret. I appreciate it very much.
-
Excellent, I'm glad you figured it out.
-
@dan How can I view RS256 secret?
It says
The private key is not viewable
-
@bharath-yadavally You don't typically view the RS256 secret for a generated key.
If you must have access to that, generate the RS256 keypair outside of FusionAuth and import the keypair.
-
@dan I forgot how I created my key at first place, imported a new one and using private key which I generated.
-
@dan Now I am able to validate the token using RS256.
But, trying to figure out how can I add a user statusACTIVE
orINACTIVE
to jwt token when generated first time by fusionauth.I previously used auth0 where we can add a js script like lambda functions to add custom parameters to jwt. Is something I could do with fusionauth?
-
@dan Discard my comment above regarding custom claims for JWT.
I found your post: https://fusionauth.io/community/forum/topic/65/how-does-one-add-custom-claims-to-the-jwt-issued-by-the-oauth-flow?_=1672715552700
Which should guide me through next steps. Thanks
-
@bharath-yadavally Glad you're getting it figured out!
-
This post is deleted! -
@raghebmichael said in Manually verifying a JWT:
Something is very wrong. I don't know if this is something anybody else is facing, but I changed to a RS256 key and used the public key on jwt.io and it is still invalid. I cannot validate a JWT outside of /api/jwt/validate. This is a really big deal to me to be able to do something as simple as validating. Please let me know if I am in error, but if I can't get this to work I cannot continue using fusionauth and that's a big bummer to me as I had high hopes for this service.
This is exactly what I was looking for to solve my problem.
Thank you very much.