TeslaGov / ngx-http-auth-jwt-module

Secure your NGINX locations with JWT
MIT License
309 stars 118 forks source link

very basic misunderstanding... #78

Closed TomaszWojtas closed 1 year ago

TomaszWojtas commented 1 year ago

Hello,

I followed the post post https://mostafa-asg.github.io/post/nginx-authentication-with-jwt/ I think it went successful, but...

I got stuck on the last stage. I think I make just some noobie mistake, but I keep receiving: 401 Authorisation required. Giving an example location:

location /test/{ auth_jwt_enabled on; auth_jwt_algorithm HS256; auth_jwt_validate_email off; auth_jwt_key "secret"; try_files /test.html /test.html; }

I assume that to get to the www.mysite.com/test/ I need to add header with JWT. So I go to jwt.io, generate the token using "secret" as the secret key to get JWT (like https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.XbPfbIHMI6arZ3Y922BhjWgQzWXcXNrz0ogtVhfEd2o).

So I authorise by adding the header and calling:

curl -H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.XbPfbIHMI6arZ3Y922BhjWgQzWXcXNrz0ogtVhfEd2o" https://www.mysite.com/test/

If you give me a hint what I am doing wrong, I would be very grateful.

Thank you very much!

Best regards Tomasz Wojtas

conor-ettinoffe commented 1 year ago

Hi @TomaszWojtas,

I'm also new to using this NGINX module and seems this repo is a bit inactive. I was experiencing the same as you but finally got it working after reading: https://github.com/benmcollins/libjwt/issues/79

I have tried and tested the following so I hope it works for you too :)

Regarding your auth_jwt_key, you should use a 32 hex pair value. You can easily generate one in Python:

In [1]: import secrets; secrets.token_hex(32).upper()
Out[1]: '2E8E27C8CF1E065DAD911992ACC9341CF4E305C0F369218A969B7105ABDE0D6F'

Then you can set as your auth_jwt_key. Note, you cannot simply pass this value as the secret in jwt.io due to the way the value is set as mentioned in the issue above.

But you can generate and test tokens locally. One thing I learnt was that the field "exp" is the only mandatory field (Token was always invalid without this field set.

With this Python snippet, you can generate a token, using the key generated above, and example payload you provided (with exp added):

import base64
import binascii
import hashlib
import hmac
import json

header ='{"alg": "HS256", "typ": "JWT"}'.encode().replace(b' ', b'')

payload = '{"sub": "1234567890",  "name": "John Doe", "iat": 1516239022, "exp": 1908835200 }'.encode().replace(b' ', b'')

signing_input = base64.urlsafe_b64encode(header).replace(
    b'=', b'')+b'.'+base64.urlsafe_b64encode(payload).replace(b'=', b'')

signature = hmac.new(binascii.unhexlify('2E8E27C8CF1E065DAD911992ACC9341CF4E305C0F369218A969B7105ABDE0D6F'),
                     signing_input, hashlib.sha256).digest().replace(b'=', b'')
signature_encoded = base64.urlsafe_b64encode(signature).replace(b'=', b'')
print((signing_input+b'.'+signature_encoded).decode())

This will give you the token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG5Eb2UiLCJpYXQiOjE1MTYyMzkwMjIsImV4cCI6MTkwODgzNTIwMH0.UxMYtK5501XWaYUMmJrsBAV6WX-oAibV1DmivA86vmU

Which will be valid :)

I hope this helps you! Took me a while to get it working

JoshMcCullough commented 1 year ago

@conor-ettinoffe thanks for lending a hand! @TomaszWojtas please report back if you've got past the issue.

JoshMcCullough commented 1 year ago

I'm going to close this issue since I think the misunderstanding is resolved.