Skip to main content

A Python library for OKTA JWT tokens validation

Project description

License Support PyPI Code Style

Okta JWT Verifier for Python

This library helps you verify tokens that have been issued by Okta. To learn more about verification cases and Okta's tokens please read Working With OAuth 2.0 Tokens

Requires Python version 3.6.0 or higher.

Release status

This library uses semantic versioning and follows Okta's Library Version Policy.

Version Status
0.x :heavy_check_mark: Beta Release

The latest release can always be found on the releases page.

Need help?

If you run into problems using the SDK, you can

Getting started

To install Okta JWT Verifier Python:

pip install okta-jwt-verifier

This library was built to keep configuration to a minimum. To get it running at its most basic form, all you need to provide is the the following information:

  • Issuer - This is the URL of the authorization server that will perform authentication. All Developer Accounts have a "default" authorization server. The issuer is a combination of your Org URL (found in the upper right of the console home page) and /oauth2/default. For example, https://dev-1234.oktapreview.com/oauth2/default.
  • Client ID - These can be found on the "General" tab of the Web application that you created earlier in the Okta Developer Console.
  • Audience - By default api://default, can be found on Authorization Servers tab.

Following example will raise an JWTValidationException if Access Token is invalid:

import asyncio

from okta_jwt_verifier import BaseJWTVerifier


async def main():
    jwt_verifier = BaseJWTVerifier(issuer='{ISSUER}', audience='api://default')
    await jwt_verifier.verify_access_token('{JWT}')
    print('Token validated successfully.')


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Usage guide

These examples will help you understand how to use this library.

Verify ID Token:

import asyncio

from okta_jwt_verifier import BaseJWTVerifier


async def main():
    jwt_verifier = BaseJWTVerifier(issuer='{ISSUER}', client_id='{CLIENT_ID}', audience='api://default')
    await jwt_verifier.verify_id_token('{JWT}', nonce='{NONCE}')
    print('Token validated successfully.')


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Note: parameter nonce is optional and required only if token was generated with nonce.

Another option - use class dedicated to ID tokens verification:

import asyncio

from okta_jwt_verifier import IDTokenVerifier


async def main():
    jwt_verifier = IDTokenVerifier(issuer='{ISSUER}', client_id='{CLIENT_ID}', audience='api://default')
    await jwt_verifier.verify('{JWT}', nonce='{NONCE}')
    print('Token validated successfully.')


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Verify Access Token

import asyncio

from okta_jwt_verifier import AccessTokenVerifier


async def main():
    jwt_verifier = AccessTokenVerifier(issuer='{ISSUER}', audience='api://default')
    await jwt_verifier.verify('{JWT}')
    print('Token validated successfully.')


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

It is possible to verify signature if JWK is provided (no async requests):

from okta_jwt_verifier import BaseJWTVerifier


def main():
    jwt_verifier = BaseJWTVerifier('{ISSUER}', '{CLIENT_ID}', 'api://default')
    jwt_verifier.verify_signature('{JWT}', {JWK})


main()

The following example shows how to receive JWK using async http request:

import asyncio

from okta_jwt_verifier import BaseJWTVerifier


async def main():
    jwt_verifier = BaseJWTVerifier('{ISSUER}', '{CLIENT_ID}', 'api://default')
    headers, claims, signing_input, signature = jwt_verifier.parse_token({JWT})
    okta_jwk = await self.get_jwk(headers['kid'])

    # Then it can be used to verify_signature as in example above.
    jwt_verifier.verify_signature('{JWT}', okta_jwk)


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

It is possible to verify only given list of claims (no async requests):

from okta_jwt_verifier import BaseJWTVerifier


def main():
    claims_to_verify = ['aud', 'iss']
    jwt_verifier = BaseJWTVerifier('{ISSUER}', '{CLIENT_ID}', 'api://default')
    headers, claims, signing_input, signature = jwt_verifier.parse_token({JWT})
    jwt_verifier.verify_claims(claims, claims_to_verify)


main()

or token expiration only (no async requests):

from okta_jwt_verifier import BaseJWTVerifier


def main():
    jwt_verifier = BaseJWTVerifier('{ISSUER}', '{CLIENT_ID}', 'api://default')
    jwt_verifier.verify_expiration('{JWT}', leeway=0)


main()

v 0.2.0 allows to work via proxy:

# BaseJWTVerifier will be deprecated soon
jwt_verifier = BaseJWTVerifier(issuer='{ISSUER}', proxy='{PROXY}')

# The same for AccessTokenVerifier
jwt_verifier = AccessTokenVerifier(issuer='{ISSUER}', proxy='{PROXY}')

# or IDTokenVerifier
jwt_verifier = IDTokenVerifier(issuer='{ISSUER}', proxy='{PROXY}')

Exceptions

If token is invalid (malformed, expired, etc.), verifier will raise an exception JWTValidationException:

import asyncio

from okta_jwt_verifier import BaseJWTVerifier


async def main():
    jwt_verifier = BaseJWTVerifier('{ISSUER}', '{CLIENT_ID}', 'api://default')
    await jwt_verifier.verify_access_token(access_token)


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Output (part of traceback removed for simplicity):

Traceback (most recent call last):
...
okta_jwt_verifier.exceptions.JWTValidationException: Signature has expired.

If configuration provided is invalid, verifier will raise an exception JWTInvalidConfigException:

import asyncio

from okta_jwt_verifier import BaseJWTVerifier


async def main():
    jwt_verifier = BaseJWTVerifier('malformed_issuer.com', '{CLIENT_ID}', 'api://default')
    await jwt_verifier.verify_access_token(access_token)


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Output (part of traceback removed for simplicity):

Traceback (most recent call last):
...
okta_jwt_verifier.exceptions.JWTInvalidConfigException: Your Okta URL must start with 'https'.

If JWK is invalid, verifier will raise an exception JWKException:

import asyncio

from okta_jwt_verifier import BaseJWTVerifier


async def main():
    jwt_verifier = BaseJWTVerifier('{ISSUER}', '{CLIENT_ID}', 'api://default')
    await jwt_verifier.verify_access_token(access_token)


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Output (part of traceback removed for simplicity):

Traceback (most recent call last):
...
okta_jwt_verifier.exceptions.JWKException: No matching JWK.

Contributing

We're happy to accept contributions and PRs! Please see the Contribution Guide to understand how to structure a contribution.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

okta_jwt_verifier-0.3.0.tar.gz (14.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

okta_jwt_verifier-0.3.0-py3-none-any.whl (15.2 kB view details)

Uploaded Python 3

File details

Details for the file okta_jwt_verifier-0.3.0.tar.gz.

File metadata

  • Download URL: okta_jwt_verifier-0.3.0.tar.gz
  • Upload date:
  • Size: 14.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for okta_jwt_verifier-0.3.0.tar.gz
Algorithm Hash digest
SHA256 1bf7c0d8100af5933b746ed4c5a7cd3d07463c9fa72b4cb7c55e215acb05abc1
MD5 9626e5d43e606b3eef6440196b23eebb
BLAKE2b-256 dd8709f472ed8b148dee3e54e6d37f14ad5e26f75a6a6b3e2c26eb96f750ed64

See more details on using hashes here.

File details

Details for the file okta_jwt_verifier-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for okta_jwt_verifier-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cf861b3c109d502e07e09b672bd857a98002c51cd599e1008bc8de29477a5dfd
MD5 10e0c4a1b5181f314bad934eb0192308
BLAKE2b-256 614838e15d79f01eeb0dc3dadff4a09f02e4d7b2a47bdc97daa807c378e40aaa

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page