Open maciejstromich opened 2 months ago
I've used jwt.decode()
to do this:
def validate(public_key: jwk.RSAKey, token: str) -> bool:
try:
jwt.decode(token, public_key)
except BadSignatureError:
return False
except JoseError:
raise # This will hit if, for instance, the token is an invalid token
else:
return True
This will just validate the signature. I combine this with a jwt.JWTClaimsRegistry
in order to do further validation of the token. This will catch things like token expiry, and you can configure it to check for the existence, and value, of certain claims like the issuer or audience.
@swails is correct. It would be great if you can show me how are you using python-jose
, I'll add a documentation about migration from python-jose
, just like https://jose.authlib.org/en/migrations/pyjwt/
The title of this issue is sufficient for me to share some of my migration experience from python-jose, so I'll just drop them here.
jose.jwt.get_unverified_header
The unverified header gives the signing key ID, so I grab the expected signing key by fetching them from the issuer and grabbing the one whose id matches what's in the header (but obviously you can't verify the token before you know which key to use).
# Equivalent to `jose.jwt.get_unverified_header`
from typing import Any
from joserfc import jws
def get_unverified_header(token: str) -> dict[str, Any]:
token_content = jws.extract_compact(token.encode())
return token_content.protected
jose.jwt.get_unverified_claims
I created an additional identity provider with the capability to create and sign tokens (storing a signing key in AWS KMS in a hardware security module). The signing key was either an Azure signing key minted by Microsoft or it was the signing key I created in AWS. In order to identify which key I should use to verify, I needed to check the issuer (it would either be Microsoft or my own). Then I would know which issuer to fetch public keys from so I could verify the signature.
# Equivalent to `jose.jwt.get_unverified_claims`
from typing import Any
from joserfc import jws
def get_unverified_claims(token: str) -> dict[str, Any]:
token_content = jws.extract_compact(token.encode())
return json.loads(token_content.payload)
thanks @swails. That helped a lot to straighten my spaghetti approach :-)
I will add also
jose.jwk.construct
from joserfc import jwk
def return_jwks_keys():
parameters = {"use": "sig", "alg": "RS256", "key_ops": ["verify"]}
return {item["kid"]: jwk.RSAKey.import_key(item, parameters=parameters) for item in jwks_json}
Currently doing migration from python-jose to joserfc and found myself in a bit of a pickle.
python-jose implementation allows validation of the token against the public_key (using verify method from RSAKey https://github.com/mpdavis/python-jose/blob/master/jose/backends/rsa_backend.py#L206).
As our codebase does that I was looking for a way to achieve the same with joserfc but the only reference to RSAKey verification I found in the docs was in https://jose.authlib.org/en/guide/jwk/#options where I can pass additional parameters to the
RSAKey.import_key
but it does not explain exactly how does the verification works. Could you shed some additional light on how to approach this issue?here's a pseudo code