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.2.7.tar.gz (14.4 kB view details)

Uploaded Source

Built Distribution

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

Uploaded Python 3

File details

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

File metadata

  • Download URL: okta_jwt_verifier-0.2.7.tar.gz
  • Upload date:
  • Size: 14.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.12.5 Darwin/23.6.0

File hashes

Hashes for okta_jwt_verifier-0.2.7.tar.gz
Algorithm Hash digest
SHA256 172cf6d9fb8e0c1bcb67a826c604ddec1b59703b5599d74bfde21f5b777647d4
MD5 e2ad0fdd8ae62ba05e9b44cd9987e25d
BLAKE2b-256 fb67e065e62e47efd2358e83a30cde6556bd96b9bb5720da3b036443ece99d12

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for okta_jwt_verifier-0.2.7-py3-none-any.whl
Algorithm Hash digest
SHA256 7578145dac767f78e351cd2733da1b211a3c3f0658c175bae4c146441e40d66b
MD5 71a3dcd61bde129c7f334df45b90c158
BLAKE2b-256 aab383b026d39fcbb5accbf0bb883b7d634ff7ec76252bd80888283607717f98

See more details on using hashes here.

Supported by

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