跳转到主要内容

简单的OIDC客户端和服务器

项目描述

oidcat

简单的OIDC。

一切都很复杂,所以我写了一个(小型)包装包,围绕 requestsflask-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 (30.8 kB 查看哈希)

上传时间

由以下支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面