Skip to content

Glocktober/JwtEncoder

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JwtEncoder

JwtEncoder provides abstracted JWT token generation (using PyJWT and validation with a dictionary configuration ment to simply creation and deployment.

Installation

# pip install JwtEncoder

Usage

Token creator:

from JwtEncoder import JwtEncoder
from config import jwt_config

jenc = JwtEncoder(jwt_config)

tok = jenc.encode({'hello': 'world', 'aud': 'xyz'})

Token consumer:

from JwtEncoder import JwtEncoder
from config import jwt_config

jenc = JwtEncoder(jwt_config)

payload = jenc.decode(tok, audience='xyz')

print(payload['hello'])  # 'world'

Signature

jenc = JwtEncoder(jwt_config=config)

jwt_config A python dict used to configure a JWT Authorizor.

  • The makeup of this dict is discussed below in more detail.
  • By default a symmetric key is generated and tokens are signed using the HS256 signing algorithm.

JwtEncoder Methods

tok = jenc.encode(payload, **kwargs)

  • Returns a JWT token tok from the dict payload with a signature and options described in jwt_config.
  • Additional options (kwargs) can be included as specified in the PyJWT documentation

pay = jenc.decode(tok, **kwargs)

  • Validates the JWT token tok and returns decoded payload pay using the signature algorithm, signing keys, and issuer specified in jwt_config.
  • Additional options (kwargs) can be provided as specified in PyJWT documentation

unverpay = jenc.decode_noverify(tok)

  • Returns contents of the payload unverpay, without verifying the signature or other jwt elements.
  • The token should be verified with jenc.decode() before any contents are used for authorization or authentication.

hdrs = jenc.header(tok)

  • Returns JWT header options.
  • The tok should be validated first with jenc.decode()

jwt_config configuration details

JwtEncoder uses the PyJWT module to implement both encoding and decoding of JWT's. The jwt_config python dict permits JwtEncoder to support a various different JWT signing methods. These include:

  • shared key signing (symmetric key)
  • public and private key (asymmetric key)
  • providing an X509 RSA certificate (asymmetric key)
  • JWKS url (asymmetric key)

The choice determines which options and which signing algorithms are valid.

shared key (symmetric key)

To use a symmetric key jwt_config is of the form:

jwt_config = {
    'key': 'mysecretkey',
    'alg': 'HS256'  # any valid JWT HS type
    'iss': 'urn:myissuer',
    'ttl': 3600 
}
  • key the value of this is the shared binary signing key, and key indicates this JwtEncoder will use symmetric key signing.
  • alg specifies the algorithm. For a symmentric key the default signing algorithm is HS256.

public/private key (asymmetric key)

pubkey and privkey (either or both) in jwt_config* indicates the JwtEncoder will use asymmetric keys for signing:

jwt_config = {
    'pubkey': b'------BEGIN PUBLIC KEY....',
    'privkey': b'------BEGIN PRIVATE KEY...',
    'alg': 'RS256',
    'iss': 'urn:myissuer'
}
  • pubkey and privkey are binary, PEM encoded keys.
  • Asymmetric signing can include RSA or elliptic curve key pairs (with the appropriate alg choice.)
  • The default algorithm (alg) is RS256 unless specified otherwise.
  • If only the pubkey is provided the JwtEncoder can only decode tokens.
  • If only the privkey is provided the JwtEncoder can only encode tokens.

X509 certificate (asymmetric key)

A binary X509 certificate indicates the JwtEncoder will use asymmetric RSA signing keys:

jwt_config = {
    'cert' : b`----BEGIN CERTIFICATE---....',
    'alg': 'RS256',
    'iss': 'urn:xyz'
}
  • cert provides only a public key, and hence only token decoding - unless a privkey is also provided in the jwt_config.
  • No validation of the X509 certificate authenticity is made.
  • The default alg is RS256

JWKS retrieval

Retrieves JASON Web Key Sets (JWKS) signing keys from the specified URL:

jst_config = {
    'jwks_url': 'https://.....',
    'iss': 'api://myapi'
}
  • This retrieves JWKS keys (for example, from an OIDC provider) The retrival specifies the algorithms used.
  • Any number of keys can be provided by the jwks_url and the decoder will use the algorithm and signing key identifier (kid) specified in the jwt header.
  • You can only decode tokens using the jwks_url method.

Additional Options

alg - algorithm

  • alg specifies the signing algorithm used.
  • For symmetric signing the default is HS256; for asymmetric signing, RS256
  • There are various signing algorithms outlined in the JWT specifications, and in the PyJWT documentation.

ttl - time to live

  • time to live is the length of time the tokens the JwtEncoder generates will be valid.
  • If ttl is not specified, 3600 Seconds is used by default.
  • The token exp value is set to the current epoch time + ttl; the token will also include nbf and iat set to the current time.
  • If ttl is explicitly set to None, the iat, nbf, and exp elements are not added to token encoding - the tokens do not expire.
  • Decoding an expired token raises an exception.

iss - issuer

  • The issuer is added as iss to the payload for encoding tokens, and is verified when tokens are decoded.
  • An alternate issuer can be specified by adding iss to the payload before calling encode({'iss': 'xyz'}), and can be verified by passing the kwarg issuer on decode (e.g. decode(token,issuer='xyz'))
  • decoding a token where the token iss doesn't match the issuer generates an exception.

Audience Validation

If a jwt has an aud (audience) element specified when encoded, then audience kwarg must be specified when decoding for the token to validate.

tok = jenc.encode({'aud': 'db21', 'scp': ['table.write']})
...
pay = jenc.decode(tok, audience=['db21', 'db22'])
  • audience can be a list, as in the example, containing multiple options. The token need only match one of them.
  • decoding a token without the matching audience generates an exception.

Generating Signing Keys

For reference only:

Generating Eliptic Curve key pairs using Openssl:

# openssl ecparam -name prime256v1 -genkey -noout -out private.pem
# openssl ec -in private.pem -pubout -out public.pem

Generating RSA key pairs using Openssl:

# openssl genrsa  -out rsaprivate.pem 2048
# openssl rsa -in rsaprivate.pem -pubout -out rsapublic.pem

About

A JwtEncoder class using PyJWT

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages