-
-
Notifications
You must be signed in to change notification settings - Fork 690
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support computation and validation of OIDC at_hash value #295
Labels
stale
Issues without activity for more than 60 days
Comments
sirosen
added a commit
to sirosen/pyjwt
that referenced
this issue
Oct 2, 2017
Use PyJWT to compute the at_hash value for OpenID Connect: http://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken This makes more sense in PyJWT than its client code because of the tight coupling between the chosen signing algorithm and the computation of the at_hash. Any client code would have to jump through hoops to get this to work nicely based on the algorithm being fed to PyJWT. Closes jpadilla#295 Primary changes: Add support for access_token=... as a param to PyJWT.encode and PyJWT.decode . On encode, the at_hash claim is computed and added to the payload. On decode, unpacks the at_hash value, raising a missing claim error if its missing, and compares it to a freshly computed at_hash. Raises a new error type if they don't match. Does not use the verification options dict, as it's redundant with the caller supplying access_token in this case. Supporting changes: - Add tests for the above - Let PyJWT and PyJWS get an algorithm object from a string as a method - Add a method, compute_at_hash, to PyJWT objects - PyJWT._validate_claims now takes the header as an arg (needed to get algo)
sirosen
added a commit
to sirosen/pyjwt
that referenced
this issue
Oct 2, 2017
Use PyJWT to compute the at_hash value for OpenID Connect: http://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken This makes more sense in PyJWT than its client code because of the tight coupling between the chosen signing algorithm and the computation of the at_hash. Any client code would have to jump through hoops to get this to work nicely based on the algorithm being fed to PyJWT. Closes jpadilla#295 Primary changes: Add support for access_token=... as a param to PyJWT.encode and PyJWT.decode . On encode, the at_hash claim is computed and added to the payload. On decode, unpacks the at_hash value, raising a missing claim error if its missing, and compares it to a freshly computed at_hash. Raises a new error type if they don't match. Does not use the verification options dict, as it's redundant with the caller supplying access_token in this case. Supporting changes: - Add tests for the above - Let PyJWT and PyJWS get an algorithm object from a string as a method - Add a method, compute_at_hash, to PyJWT objects - PyJWT._validate_claims now takes the header as an arg (needed to get algo)
sirosen
added a commit
to sirosen/pyjwt
that referenced
this issue
Oct 2, 2017
Use PyJWT to compute the at_hash value for OpenID Connect: http://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken This makes more sense in PyJWT than its client code because of the tight coupling between the chosen signing algorithm and the computation of the at_hash. Any client code would have to jump through hoops to get this to work nicely based on the algorithm being fed to PyJWT. Closes jpadilla#295 Primary changes: Add support for access_token=... as a param to PyJWT.encode and PyJWT.decode . On encode, the at_hash claim is computed and added to the payload. On decode, unpacks the at_hash value, raising a missing claim error if its missing, and compares it to a freshly computed at_hash. Raises a new error type if they don't match. Does not use the verification options dict, as it's redundant with the caller supplying access_token in this case. Supporting changes: - Add tests for the above - Let PyJWT and PyJWS get an algorithm object from a string as a method - Add a method, compute_at_hash, to PyJWT objects - PyJWT._validate_claims now takes the header as an arg (needed to get algo)
sirosen
added a commit
to sirosen/pyjwt
that referenced
this issue
Oct 19, 2017
Use PyJWT to compute the at_hash value for OpenID Connect: http://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken This makes more sense in PyJWT than its client code because of the tight coupling between the chosen signing algorithm and the computation of the at_hash. Any client code would have to jump through hoops to get this to work nicely based on the algorithm being fed to PyJWT. Closes jpadilla#295 Primary changes: Add support for access_token=... as a param to PyJWT.encode and PyJWT.decode . On encode, the at_hash claim is computed and added to the payload. On decode, unpacks the at_hash value, raising a missing claim error if its missing, and compares it to a freshly computed at_hash. Raises a new error type if they don't match. Does not use the verification options dict, as it's redundant with the caller supplying access_token in this case. Supporting changes: - Add tests for the above - Let PyJWT and PyJWS get an algorithm object from a string as a method - Add a method, compute_at_hash, to PyJWT objects - PyJWT._validate_claims now takes the header as an arg (needed to get algo)
sirosen
added a commit
to sirosen/pyjwt
that referenced
this issue
Jan 10, 2018
The JWTPayload class allows PyJWT.decode() to expose header, signature, signing_input, and compute_hash_digest() (based on header) without changing the pyjwt API in a breaking way. Merely making this info accessible to the client (without specify an additional verification callback scheme) is simpler for everyone. Include doc on why JWTPayload is a good idea (in a docstring), since it's a little unusual to subclass `dict`. The intent is to make the JWT payload change as little as possible while still making it easy to add more verification after the fact. Add a simple test for `JWTPayload.compute_hash_digest()` Closes jpadilla#314, jpadilla#295
sirosen
added a commit
to sirosen/pyjwt
that referenced
this issue
Jan 10, 2018
The JWTPayload class allows PyJWT.decode() to expose header, signature, signing_input, and compute_hash_digest() (based on header) without changing the pyjwt API in a breaking way. Merely making this info accessible to the client (without specify an additional verification callback scheme) is simpler for everyone. Include doc on why JWTPayload is a good idea (in a docstring), since it's a little unusual to subclass `dict`. The intent is to make the JWT payload change as little as possible while still making it easy to add more verification after the fact. Add a simple test for `JWTPayload.compute_hash_digest()` Closes jpadilla#314, jpadilla#295
sirosen
added a commit
to sirosen/pyjwt
that referenced
this issue
Jan 10, 2018
The JWTPayload class allows PyJWT.decode() to expose header, signature, signing_input, and compute_hash_digest() (based on header) without changing the pyjwt API in a breaking way. Merely making this info accessible to the client (without specify an additional verification callback scheme) is simpler for everyone. Include doc on why JWTPayload is a good idea (in a docstring), since it's a little unusual to subclass `dict`. The intent is to make the JWT payload change as little as possible while still making it easy to add more verification after the fact. Add a simple test for `JWTPayload.compute_hash_digest()` Closes jpadilla#314, jpadilla#295
sirosen
added a commit
to sirosen/pyjwt
that referenced
this issue
May 14, 2020
The JWTPayload class allows PyJWT.decode() to expose header, signature, signing_input, and compute_hash_digest() (based on header) without changing the pyjwt API in a breaking way. Merely making this info accessible to the client without specifying an additional verification callback scheme is simpler for everyone. Include doc on why JWTPayload is a good idea in a module docstring, since it's a little unusual to subclass `dict`. The intent is to make the JWT payload change as little as possible while still making it easy to add more verification after the fact. Add a simple test for `JWTPayload.compute_hash_digest()` and a test for compute_hash_digest with cryptography (which is compared against a manual hashlib usage). Closes jpadilla#314, jpadilla#295
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days |
sirosen
added a commit
to sirosen/pyjwt
that referenced
this issue
Jun 29, 2022
Looking up an algorithm by name is used internally for signature generation. This encapsulates that functionality in a dedicated method and adds it to the public API. No new tests are needed to exercise the functionality. Rationale: 1. Inside of PyJWS, this improves the code. The KeyError handler is better scoped and the signing code reads more directly. 2. This is part of the path to supporting OIDC at_hash validation as a use-case (see: jpadilla#295, jpadilla#296, jpadilla#314). This is arguably sufficient to consider that use-case supported and close it. However, it is an improvement and step in the right direction in either case.
sirosen
added a commit
to sirosen/pyjwt
that referenced
this issue
Jun 29, 2022
Looking up an algorithm by name is used internally for signature generation. This encapsulates that functionality in a dedicated method and adds it to the public API. No new tests are needed to exercise the functionality. Rationale: 1. Inside of PyJWS, this improves the code. The KeyError handler is better scoped and the signing code reads more directly. 2. This is part of the path to supporting OIDC at_hash validation as a use-case (see: jpadilla#295, jpadilla#296, jpadilla#314). This is arguably sufficient to consider that use-case supported and close it. However, it is an improvement and step in the right direction in either case.
sirosen
added a commit
to sirosen/pyjwt
that referenced
this issue
Jun 29, 2022
Looking up an algorithm by name is used internally for signature generation. This encapsulates that functionality in a dedicated method and adds it to the public API. No new tests are needed to exercise the functionality. Rationale: 1. Inside of PyJWS, this improves the code. The KeyError handler is better scoped and the signing code reads more directly. 2. This is part of the path to supporting OIDC at_hash validation as a use-case (see: jpadilla#295, jpadilla#296, jpadilla#314). This is arguably sufficient to consider that use-case supported and close it. However, it is an improvement and step in the right direction in either case. A minor change was needed to satisfy mypy, as a union-typed variable does not narrow its type based on assignments. The easiest resolution is to use a new name, in this case, simply `algorithm -> algorithm_`.
jpadilla
pushed a commit
that referenced
this issue
Jul 3, 2022
* Expose get_algorithm_by_name as new method Looking up an algorithm by name is used internally for signature generation. This encapsulates that functionality in a dedicated method and adds it to the public API. No new tests are needed to exercise the functionality. Rationale: 1. Inside of PyJWS, this improves the code. The KeyError handler is better scoped and the signing code reads more directly. 2. This is part of the path to supporting OIDC at_hash validation as a use-case (see: #295, #296, #314). This is arguably sufficient to consider that use-case supported and close it. However, it is an improvement and step in the right direction in either case. A minor change was needed to satisfy mypy, as a union-typed variable does not narrow its type based on assignments. The easiest resolution is to use a new name, in this case, simply `algorithm -> algorithm_`. * Use get_algorithm_by_name in _verify_signature Rather than catching the KeyError from a dict lookup, catch the NotImplementedError raised by get_algorithm_by_name. This changes the exception seen in the cause under exception chaining but otherwise has no public-facing impact.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Open ID Connect specifies an optional additional claim for its ID token JWTs: the
at_hash
.It's just a hash of the access token issued alongside the ID token.
Although OIDC lists it as optional, it also states that it's required when performing the "Authorization Code Grant" (3-legged OAuth), which is confusing.
It's very easy to compute. Just
replacing
hashlib.sha256
with whateveralg
is specified.For those implementing OIDC servers, and clients of those servers, computing and validating this
at_hash
value, respectively, makes sense as PyJWT functionality.The text was updated successfully, but these errors were encountered: