简单的OIDC客户端和服务器
项目描述
oidcat
简单的OIDC。
一切都很复杂,所以我写了一个(小型)包装包,围绕 requests
和 flask-oidc
,提供了一个(稍微)更容易的接口来保护和连接到私有资源。
我没有时间等待 flask_oidc
中的PR合并,但也许最终我会将其中的部分合并!
安装
pip install oidcat
用法
客户端
这是一个将完全为您处理令牌的 requests.Session
对象。无需刷新令牌,当您的访问和刷新令牌都过期时,无需手动重新登录。
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()
资源服务器
这是一个资源服务器的示例。
注意:技术上您可以在不创建客户端的情况下做到这一点(在
with_well_known_secrets_file
中省略它们),并且它将使用admin-cli
客户端。
import os
import flask
import oidcat.server
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'),
)
import sqlitedict
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(role='editor') # client/realm role
def edit():
'''This will give a 402 if you don't pass `access_token`.'''
return flask.jsonify({'message': 'you did something!'})
@app.route('/edit')
@oidc.accept_token(role='editor', realm=False) # 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(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)
变更
会话
- 添加
Access
抽象,它封装了访问和刷新令牌、已知信息和登录/注销逻辑。 - 访问令牌将自动通过Bearer令牌方法添加到请求中。
- 要按请求禁用此功能,请将
token=False
传递给您的请求方法(例如sess.get(..., token=False)
) - 要针对对象上的所有请求禁用此功能,您可以使用
Session(..., require_token=False)
- 要按请求重新启用此功能:
sess.get(..., token=False)
- 要按请求禁用此功能,请将
- 添加一个
login
/logout
方法(这是Access对象的便利包装器)
- 添加
令牌
- 添加一个令牌类,它封装了令牌、令牌数据和过期逻辑
- 令牌的真值可以用来确定是否需要刷新
- 添加令牌检查函数
has_role
服务器
:-
accept_token
接受额外的参数role (str, list)
:检查令牌中的角色client (str, bool, default=True)
:见has_role
checks (list of callables)
:您可以传递任意
-
has_role
检查令牌中的Keycloak角色。目前我们只支持与Keycloak兼容的令牌格式*roles (tuple[str])
:要比较的角色client_id (str, bool, default=True)
:如果是一个字符串,将检查该client_id中的角色。如果是True,将检查当前客户端。如果是False/None,将检查领域角色。
-
util.with_keycloak_secrets_file
:生成客户端密钥文件并返回其路径。参见上面的用法。- 这还处理了从基本URL的所有附加URL(令牌内省等)。
-
项目详情
关闭
oidcat-0.5.2.tar.gz的哈希
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 533bf1dc3139b61d6d0742bd3f494a68c9cc6ffc8d8b83bbacbb71dbb2e2086d |
|
MD5 | 9ad1133608186ed750a7d34790a3b09c |
|
BLAKE2b-256 | 382e706dfc638eb85e53b6fa9fbb634d202787d351d2a4eb88ba665e02b5d28e |