Skip to main content

A package for creating a client credentials oAuth2.0 workflow.

Project description

Welcome to Steelcut-OAuth

A tool written in Python 3.13 to implement OAuth2.0 using the client credentials grant type. This is intended for machine to machine APIs and integrates with a PostgreSQL server for storing client ids and hashed/salted client secrets. Please see requirements.txt for the full list of dependencies.

Installation

Prior to installing this Python package, PostgreSQL must be installed on the target machine. This README is focused on Linux; however, with appropriate adjustments the program should run on Windows and Mac OS as well.

Install PostgreSQL:
sudo apt install postgresql

Install all psycopg build prerequistes including libpq and python3-dev.

PostgreSQL will create a postgres superuser by default. We recommend creating two new users: one user that creates a table for storing client ids and hashed/salted client secrets and one user that has "SELECT" only rights to the table. This can be created as follows:

  1. sudo -s to switch to root.

  2. su - postgres to switch to postgres super user.

  3. psql to launch the postgreSQL cli.

  4. CREATE USER your_admin_username WITH PASSWORD 'your_password';

    For the admin that will create and maintain the database of client ids and secrets we suggest a user name that is meaningful to the specific user and a strong password.

  5. CREATE USER your_viewer_username WITH PASSWORD 'your_password';

    For the viewer that will have "SELECT" only privileges, we suggest "auth_client" for the user name and a strong password.

    Create the database that will store the credentials. We suggest using 'clientdb'.

  6. CREATE DATABASE clientdb;

  7. exit to exit the psql cli.

  8. su - your-admin-username to switch to admin user and use the strong password that was created for this admin.

    Create the table to store client credentials. We suggest "stored_tokens".

  9. CREATE TABLE stored_tokens;

  10. GRANT SELECT ON stored_tokens TO auth_client; to allow the viewer user access to view the contents of the table.

After all the prerequisites have been met, you can install the package:

pip install steelcut-oauth

Program Structure

The oauth_client package contains three (3) critical components for enabling OAuth.

  1. Client creation using client ids and client secrets.

  2. An Authorization server that checks that a client is allowed access to the protected resource and grants a json web token (jwt).

  3. A Protected Resource Server that verifies that the token is valid and responds with a protected json file.

    For more details, click this link for the full OAuth2.0 Specification

Example Usage

The following examples demonstrate some of the basic capabilities. Please note that it is up to the user to ensure that they maintain good separation of resources. For instance, the Authorization server and Resource server should not reside on the same server. Similarly, the client data should not reside with the resource server.

Create the OAuth Class

from oauth_client import OAuth, client_request_token, client_request_resource

oauth = OAuth(db_name='clientdb',
              db_host='127.0.0.1',
              db_table_name='stored_tokens',
              db_create_table=False,
              resource_owner_username='admin',
              jwt_issuer='admin',
              jwt_audience='client',
              jwt_subject='client')

Create a Signature

This creates assymetric public and private key pairs for the admin. The signature is required for the admin to sign jwt tokens and is stored in a keyring. The private key and public key are both required to sign the jwt; however, only the public key is used to validate that the jwt is authentic. The signature should be stored on the authorization server.

oauth.create_signature()

Create a New Authorized Client

Note The client secret will be printed locally to the terminal. It will not be retrievable again after. All of the client ids and secrets are for demonstration purposes only. Please do not ever share or store client secrets in plain text.

oauth.add_client(client_name='Jane Doe',
                 grant_type='client_credentials',
                 resource='api_v0.0.1')
# this will print the following to the console:
# {
# "grant_type": "client_credentials",
# "client_id": "0083c1b7e3a6ceeac4a4f47bd3a1b501",
# "client_secret": "PRIVATE-qGSUlXIyQVFB_xfPnHOy6WWGMER5uCgZyaKWgJw-ggQ"
# "resource": "api_v0.0.1"
# }

Make Changes to an Existing Client

Client grant type and resource can be modified in the database. In addition, a new client secret can be generated if new_client_secret is set to True.

oauth.update_client(client_id='0083c1b7e3a6ceeac4a4f47bd3a1b501',
                    grant_type='another grant type',
                    resource='another resource',
                    new_client_secret=True)

Run the Authorization Server

The authorization server is a Flask server configured with a "/token" route.

app = oauth.auth_server()
app.run(debug=True)

The run method of app is appropriate for testing locally. In production, please use a WSGI production server such as Gunicorn

Request a Token

The Authorization server must be running to request a token.

token = client_request_token('client_credentials',
                             '0083c1b7e3a6ceeac4a4f47bd3a1b501',
                             'PRIVATE-qGSUlXIyQVFB_xfPnHOy6WWGMER5uCgZyaKWgJw-ggQ',
                             'api_v0.0.1',
                             'http://127.0.0.1:5001/token')

Run the Resource Server

The resource server is a Flask server. The user can specify two parameters:

  1. The default api route ('api_v0.0.1' in the example below).
  2. The path and filename of the protected resource. Note the protected resource must be a json file.
  3. As with the Authorization server, the run method is appropriate for local testing but a production WSGI server should be used in production.
app = oauth.resource_server('api_v0.0.1','protected_resource.json')
app.run(debug=True, port=5001)

Request Protected Resource

The Resource Server must be running to request the protected resource. Note The route /api_v0.0.1 is the same route specified when starting the Resource Server.

# This uses the token variable from the initial token request.
client_request_resource('http://127.0.0.1:5001/api_v0.0.1',token)
# returns the protected resource as a json string.
# {"about": "This is a protected resource"}

Future Efforts

Add targeted error handling classes to improve user experience.

License

MIT

Authors

John Glauber

Contact

For any questions, comments, or suggestions please reach out via email to:

johnbglauber@gmail.com
https://github.com/jglauber/OAuth

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

steelcut_oauth-0.0.1.tar.gz (20.8 kB view details)

Uploaded Source

Built Distribution

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

steelcut_oauth-0.0.1-py3-none-any.whl (21.4 kB view details)

Uploaded Python 3

File details

Details for the file steelcut_oauth-0.0.1.tar.gz.

File metadata

  • Download URL: steelcut_oauth-0.0.1.tar.gz
  • Upload date:
  • Size: 20.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.2

File hashes

Hashes for steelcut_oauth-0.0.1.tar.gz
Algorithm Hash digest
SHA256 f8ae5fbae3ebe7e36414b7dd566676c0ec3baa8600f89dd6e3ae9388dd3492a5
MD5 401222a294e15b090e4b98b18eb8f955
BLAKE2b-256 bc0d8b6a5405dddffc1a74e4a0af49b162c6b16cdbe8d4ddac604747e576e468

See more details on using hashes here.

File details

Details for the file steelcut_oauth-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: steelcut_oauth-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 21.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.2

File hashes

Hashes for steelcut_oauth-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c8c281ea94dcfab0f28faded9ccb8b0af46fe0399b82cf32e68ea49bd8dff767
MD5 864bfa5a67fccbff204cc10bce55c37a
BLAKE2b-256 85f4341620efa3eeeecdc499712b6088a79818732d701856811cb7b34c4d3c55

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