easy oidc client & server
Project description
oidcat
Simple OIDC.
It's all so confusing, so I wrote a (small) wrapper package around requests
and flask-oidc
that provides a (slightly) easier interface to protect and connect to private resources.
I don't have time to wait for PRs to merge in flask_oidc
, but maybe I'll get some of this merged eventually!
Install
pip install oidcat
Usage
Client
This is a requests.Session
object that will handle tokens entirely for you. No need to refresh tokens, no need to manually log back in when both your access and refresh tokens expire.
import os
import oidcat
# basic login:
sess = oidcat.Session('auth.myapp.com', os.getenv('USERNAME'), os.getenv('PASSWORD'))
# that's it! all future requests will use the token
# and it will automatically refresh so effectively, it'll never expire!
out = sess.get('https://api.myapp.com/view').json()
Resource Server
Here's an example resource server.
NOTE: Technically you can do this without creating a client (and omit them in
with_well_known_secrets_file
) and it will use theadmin-cli
client.
import os
import flask
import oidcat.server
import sqlitedict
app = flask.Flask(__name__)
app.config.update(
# Create the client configuration (makes request to well known url)
OIDC_CLIENT_SECRETS=oidcat.util.with_well_known_secrets_file(
'auth.myapp.com', 'myclient', 'supersecret'),
# or:
# Create keycloak client configuration (doesn't need request)
# OIDC_CLIENT_SECRETS=oidcat.util.with_keycloak_secrets_file(
# 'auth.myapp.com', 'myclient', 'supersecret', 'myrealm'),
)
oidc = oidcat.server.OpenIDConnect(app, credentials_store=sqlitedict.SqliteDict('creds.db', autocommit=True))
# or equivalently:
oidc = oidcat.server.OpenIDConnect(app, 'creds.db')
# various forms of protecting endpoints
@app.route('/')
@oidc.require_login
def index():
'''This will redirect you to a login screen.'''5
return flask.jsonify({'message': 'Welcome!'})
# question - what exactly is the difference between these?
@app.route('/edit')
@oidc.accept_token(keycloak_role='editor') # client role
def edit():
'''This will give a 402 if you don't pass `access_token`.'''
return flask.jsonify({'message': 'you did something!'})
@app.route('/view')
@oidc.accept_token(scopes_required='reader') # client scopes
def view():
'''This will give a 402 if you don't pass `access_token`.'''
return flask.jsonify({'message': 'something interesting!'})
@app.route('/ultimatepower')
@oidc.accept_token(keycloak_role='admin', client=None) # realm role
def ultimatepower():
'''This will give a 402 if you don't pass `access_token`.'''
return flask.jsonify({'message': 'mwahahah!'})
if __name__=='__main__':
app.run(host='0.0.0.0', port=PORT, debug=True)
Changes
-
accept_token
takes additional parameters:keycloak_role (str, list)
: roles to check for in the tokenclient (str, bool, default=True)
: seehas_keycloak_role
checks (list of callables)
: you can pass arbitrary
-
has_keycloak_role
checks for keycloak roles in the token (in master, but not current release)role (str, list)
: the roles to compare againstclient (str, bool, default=True)
: if a string, it will check for roles in that client-id. If True, it will check in the current client. If False/None, it will check for realm roles.
-
util.with_keycloak_secrets_file
: generate the client secrets file and return the path to it. See usage above.- this also handles all of the additional urls (token introspection, etc) from the base url.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file oidcat-0.1.0.tar.gz
.
File metadata
- Download URL: oidcat-0.1.0.tar.gz
- Upload date:
- Size: 8.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/50.3.0.post20201103 requests-toolbelt/0.9.1 tqdm/4.45.0 CPython/3.7.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 57480715c14fb0d432dba05124828c3c591f23ff00f676fa98b7fc036ab57c7c |
|
MD5 | 7fb4dbc023859a3d6e2b5cd7ed7e9ed1 |
|
BLAKE2b-256 | 60c8d1a9868c843d2aec45e44e170e257e7b8e719403f216c0bbd798df3f01ad |