DEV Community

Pete Letkeman
Pete Letkeman

Posted on • Updated on

Secure Python Litestar Site With OpenID/OIDC Using Okta Hosted Login

Here is a tutorial on how to setup OKTA as a OpenID/OIDC security provider for a site programmed in Python 3.11.x using Litestar.
This is done with 'Authorization Code flow'

About the Authorization Code grant

The Authorization Code flow is the recommended method for controlling access to web applications capable of securely storing secrets, see https://developer.okta.com/docs/guides/implement-grant-type/authcode/main/

OKTA Setup

Step 1

After you have created your OKTA account open `Applications` => `Applications` as seen on the right.

Step 2

Click Create App Integration
Image description

Step 3

Choose OIDC - Open Connect with a description of
'Token-based OAuth 2.0 authentication for Single Sign-On (SSO) through API endpoints. Recommended if you intend to build a custom app integration with the Okta Sign-In Widget.'
Image description

And then choose Web Application with a description of
'Server-side applications where authentication and tokens are handled on the server (for example, Go, Java, ASP.Net, Node.js, PHP)'

And Click Next

Step 4

Checked the following (may not matter):

  • Client Credentials
  • Refresh Token
  • Implicit (hybrid)

Image description

Step 5

Ensure that both Sign-in redirect URIs and Sign-out redirect URIs (Optional) have the correct values. By default Litestar brings up the web site on port 8000.
Image description

Step 6

In Assignments select Allow everyone in your organization to access.
In Enable immediate access (Recommended) select Enable immediate access with *Federation Broker Model*
Click Save
Image description

Step 7

Create a text file named '.env' and from the General tab, copy both Client ID and Client Secret to the file to have something like the following:

CLIENT_ID=your_client_id
CLIENT_SECRET=your_client_secret
OKTA_DOMAIN=dev-123456789.okta.com
REDIRECT_URL=http://localhost:8000/authorization-code/callback
OKTA_PROMPT=consent
Enter fullscreen mode Exit fullscreen mode

And provide the you value for OKTA_DOMAIN.

You do not to supply a value for OKTA_PROMPT or even include it if you choose not to. For more details about regarding this parameter see https://developer.okta.com/docs/reference/api/oidc/#parameter-details.
Using OKTA_PROMPT is very helpful when testing multiple user accounts.

Python Code

Github.com repository found here https://github.com/pbaletkeman/litestarOpenID

Copy the .env file from the previous step to the root directory of your Python project.

For the most part the code is well documented, however here are some notes:

  • It uses Mako templates, https://www.makotemplates.org/
  • /profile is not secured, and is used to show you JWT Bearer Token which is needed to access /read-items and other secure routes, this is set in the callback method
  • More user properties are found in the user_response object located in the callback method

Additionality PKCE

You can use Authorization Code Grant with Proof Key for Code Exchange (PKCE) which you can read about here:
https://developer.okta.com/docs/guides/implement-grant-type/authcodepkce/main/#about-the-authorization-code-grant-with-pkce.

To enforce PKCE you will have to select 'Require PKCE as additional verification' as seen in the image below.
Image description
You can still use PKCE without requiring it.

Here is the Python code for this,
https://github.com/pbaletkeman/okta-litestar-oidc-pkce
Which is a lot like the none PKCE code.
Note that the following have been added/changed:

lines: 181, 182, 192, 193

'code_challenge': code_challenge,
'code_challenge_method': 'S256',
Enter fullscreen mode Exit fullscreen mode

line: 231
query_params = {'grant_type': 'authorization_code', 'code': code,

line: 185, 197
And the response_mode has been changed from 'query' to 'form_post' which tells OKTA to send the data as a form post instead of using the query string. Query string is still valid and can be used if you choose to.

Top comments (0)