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.5.0.tar.gz (15.4 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.5.0-py3-none-any.whl (16.5 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for okta_jwt_verifier-0.5.0.tar.gz
Algorithm Hash digest
SHA256 4fe6e4f4ffff6c03b6b63a7709b879bdaf57025ae1dcc06ea2f32dd4a07963df
MD5 659d235fcff7c642c1ef3d6c641626ee
BLAKE2b-256 d0b63e85f92cbb851c2bd57b67efcb8485c1f88f595dba1f072d688a3802dee1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for okta_jwt_verifier-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 af41e947759ffeb65149aeafb81c065c1eeb4eeda5880f0b9d755a96f1db1cee
MD5 acd33cd5025c9c78b7deaac6650d341a
BLAKE2b-256 08f2add78bad59c902a0c97ebdc8bf193b8364fdac3ea87148948018f3835095

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