Skip to content
This repository has been archived by the owner on Mar 31, 2019. It is now read-only.

creating a token with a struct will fail validation #7

Open
aricart opened this issue Aug 15, 2018 · 6 comments
Open

creating a token with a struct will fail validation #7

aricart opened this issue Aug 15, 2018 · 6 comments
Labels

Comments

@aricart
Copy link

aricart commented Aug 15, 2018

When creating a token with a struct, the struct is serialized and rendered properly. It also looks good on tools like jwt.io. When the token is decoded, any calls to validate it fails.
sample token:

eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6IkFEQUlMR1ZZMlc0UEpBVFlPTUhBT0lZTlREVUNNVlRaT1pCSUlDNlJXNEZNUERCNkY3QjZHSjNQIn0.eyJVc2VyS2V5IjoiVUFLSVpZSks3M0cyU1U3U1JaNzY1TlBGVENWVE1PUU5ENFdIUkVFQjIzT0g2WkVZRDRBWUtOVVkiLCJTdWJBY2wiOlsiZm9vIl0sIlB1YkFjbCI6WyJmb28iXSwiTGltaXRzIjp7Im1wcyI6MH19.9urPSuMpMZeEL2FkhL2bWN9MWJ-m6-92OtFUDcuzzGNWSgbXtwzabTIml_wrP66UQbFdkD5rlkKklvGz4OgZCQ
Error validating the JWT token: hash does not match content

If the same struct is serialized as a JSON into a map[string]interface{}, the token can be decoded and validated correctly. The JSON representation of the token is not nice to read on jwt.io (and it is larger):

eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6IkFEQUlMR1ZZMlc0UEpBVFlPTUhBT0lZTlREVUNNVlRaT1pCSUlDNlJXNEZNUERCNkY3QjZHSjNQIn0.eyJuYXRzIjoie1xuICBcIlVzZXJLZXlcIjogXCJVQUtJWllKSzczRzJTVTdTUlo3NjVOUEZUQ1ZUTU9RTkQ0V0hSRUVCMjNPSDZaRVlENEFZS05VWVwiLFxuICBcIlN1YkFjbFwiOiBbXG4gICAgXCJmb29cIlxuICBdLFxuICBcIlB1YkFjbFwiOiBbXG4gICAgXCJmb29cIlxuICBdLFxuICBcIkxpbWl0c1wiOiB7XG4gICAgXCJtcHNcIjogMFxuICB9XG59In0.dQAxuUZ04NgMbhbeE7Q53TnjWZYv4S543V3jQPTWe0mFXWMalDELYvwV6FY93QQ4SGEnMiQTWIJPF5IN27XADA

but decodes correctly

ngsauth decode eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6IkFEQUlMR1ZZMlc0UEpBVFlPTUhBT0lZTlREVUNNVlRaT1pCSUlDNlJXNEZNUERCNkY3QjZHSjNQIn0.eyJuYXRzIjoie1xuICBcIlVzZXJLZXlcIjogXCJVQUtJWllKSzczRzJTVTdTUlo3NjVOUEZUQ1ZUTU9RTkQ0V0hSRUVCMjNPSDZaRVlENEFZS05VWVwiLFxuICBcIlN1YkFjbFwiOiBbXG4gICAgXCJmb29cIlxuICBdLFxuICBcIlB1YkFjbFwiOiBbXG4gICAgXCJmb29cIlxuICBdLFxuICBcIkxpbWl0c1wiOiB7XG4gICAgXCJtcHNcIjogMFxuICB9XG59In0.dQAxuUZ04NgMbhbeE7Q53TnjWZYv4S543V3jQPTWe0mFXWMalDELYvwV6FY93QQ4SGEnMiQTWIJPF5IN27XADA
map[nats:{
  "UserKey": "UAKIZYJK73G2SU7SRZ765NPFTCVTMOQND4WHREEB23OH6ZEYD4AYKNUY",
  "SubAcl": [
    "foo"
  ],
  "PubAcl": [
    "foo"
  ],
  "Limits": {
    "mps": 0
  }
}]
@FossoresLP
Copy link
Owner

I'm sorry, I've totally missed this issue. I'll look into it ASAP. Stay tuned in case you still use this package.

@FossoresLP
Copy link
Owner

FossoresLP commented Dec 1, 2018

Looking at the validation function it seems like this issue is caused by the way Go decodes JSON. Since Go can't figure out the type it decodes JSON as a map[string]interface{} by default. This causes the encoding by the validation function to turn out differently from the original data.

There are a few options to fix this:

  • Validating during decoding (Would mean the Validate function would vanish)
  • Introducing a static type into the decode function (Content will be decoded into a struct supplied by the user)
  • Storing the original, encoded content and checking for changes to the decoded data by decoding it again before validating the original content (This is probably the least problematic solution but it would still require changes to the JWT struct and would also slow down validation considerably due to the need to compare the two maps using reflect.DeepEqual())

Most if not all of these will be breaking changes. I really would to keep those to a minimum since normal Go packages like this are not versioned. To find the best solution for the future it would be great if someone else could weigh in. I really don't know what the best option is right now.

@FossoresLP
Copy link
Owner

I have created a test that checks for this issue which I will submit as a PR in case anyone else would like to help. Still have no idea how to fix it without breaking the whole package though.

Since I have planned to add Ed448 support for some time, I will check if there is finally a package I can use. Then I would consider moving this project to a new repo (to improve the name) which would make breaking changes a lot less problematic.

@FossoresLP
Copy link
Owner

After looking at this a little more in-depth I have found out that this problem is caused by Go ordering the decoded content alphabetically. I have updated the tests accordingly.

As a workaround to get this to work you should just order your structs alphabetically and the will be no issues. I know however that this is not a real solution since this package is expected to handle data from other sources, too. Therefore I will try to preserve the order of any content or delegate the complete handling of any content to the user while just validating the encoded data.

@FossoresLP
Copy link
Owner

I have added a notice to the README to inform users about this issue and I will try to fix it but that could still be a problem with backwards compatibility.

@FossoresLP FossoresLP added bug and removed enhancement labels Dec 3, 2018
@FossoresLP
Copy link
Owner

This project is now deprecated in favor of go-jwt which does not have the same issue. In case you come across this issue I would recommend switching to that instead.

I'm leaving this issue open since it has not been fixed in this repository but I don't plan on fixing it.

@FossoresLP FossoresLP removed their assignment Mar 25, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants