Skip to content
This repository has been archived by the owner on Nov 13, 2023. It is now read-only.

Header Parameter kid not implemented in the context of verifying , even though check optional is false #13

Closed
allan-simon opened this issue Mar 4, 2016 · 8 comments

Comments

@allan-simon
Copy link

it seems to be caused by jws , which does check all of them and throw an error

https://github.com/brianloveswords/python-jws/blob/master/jws/header.py#L52

@davedoesdev
Copy link
Owner

Thanks for the heads up. If checks_optional is False then checks should be made.
Do you mean when checks_optional is True?

@davedoesdev
Copy link
Owner

OK I've written a test which fails on a token which has a kid header.
I'm going to see if I can get checks_optional=True to relax the checks that JWS makes.

@davedoesdev
Copy link
Owner

I have a fix too. It's not pretty (it relies on monkey patching jws.header and using thread local storage). Gonna mull it over for a little while before pushing it in case something else occurs to me.
@allan-simon (or anyone else who might be watching), what do you think?
I don't really want to change any of the processing that jws does (e.g. in jws.header.process) because then I might miss when jws updates. Also, this solution fails safe (callers to jws from other packages won't have the not-implemented exceptions disabled).

diff --git a/jwt/__init__.py b/jwt/__init__.py
index 88ef6e9..aec7e05 100644
--- a/jwt/__init__.py
+++ b/jwt/__init__.py
@@ -2,6 +2,7 @@
 Functions for generating and verifying JSON Web Tokens.
 """

+import threading
 from datetime import datetime, timedelta
 from calendar import timegm
 from base64 import urlsafe_b64encode
@@ -17,6 +18,19 @@ jws._signing_input = lambda head, payload, is_json=False: \
               map(jws.utils.to_base64 if is_json else jws.utils.encode,
                   [head, payload])])

+_tls = threading.local()
+
+class _VerifyNotImplemented(jws.header.VerifyNotImplemented):
+    def verify(self):
+        if getattr(_tls, 'checks_optional', False):
+            return self.value
+        return super(_VerifyNotImplemented, self).verify()
+
+for header in jws.header.KNOWN_HEADERS:
+    cls = jws.header.KNOWN_HEADERS[header]
+    if cls == jws.header.VerifyNotImplemented:
+        jws.header.KNOWN_HEADERS[header] = _VerifyNotImplemented
+
 class _JWTError(Exception):
     """ Exception raised if claim doesn't pass. Private to this module because
         jws throws many exceptions too. """
@@ -140,7 +154,11 @@ def verify_jwt(jwt,
     claims = jws.utils.from_base64(claims).decode('utf-8')

     if pub_key:
-        jws.verify(header, claims, sig, pub_key, True)
+        _tls.checks_optional = checks_optional
+        try:
+            jws.verify(header, claims, sig, pub_key, True)
+        finally:
+            _tls.checks_optional = False
     elif 'none' not in allowed_algs:
         raise _JWTError('no key but none alg not allowed')

@davedoesdev
Copy link
Owner

I think it might be best to make it a separate parameter (e.g. verify_not_implemented=True).

@allan-simon
Copy link
Author

agreed for the verify_not_implemented

@davedoesdev
Copy link
Owner

@allan-simon please try version 1.2.0 and let me know if it works for you.
There is a new parameter, ignore_not_implemented: http://rawgit-davedoesdev.rhcloud.com/davedoesdev/python-jwt/master/docs/_build/html/index.html#jwt.verify_jwt

@allan-simon
Copy link
Author

seems to work, thanks :)

@davedoesdev
Copy link
Owner

You're welcome, thanks for letting me know - appreciate it.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants