我能够使用此处理程序扩展 oidc 烧瓶示例
@bp.route("/.well-known/openid-configuration")
def well_known_openid_configuration():
def external_url(function_name):
return url_for(function_name, _external=True)
return jsonify({
"authorization_endpoint": external_url('.authorize_endpoint'),
"token_endpoint": external_url('.token_endpoint'),
"userinfo_endpoint": external_url('.userinfo_endpoint'),
"jwks_uri": external_url('.jwks_endpoint'),
# Do I even need this one?
# IMO the OIDC server doesn't have a concept of a user being still logged in? --mh
# "end_session_endpoint": "http://oidc:4000/openid/end-session",
"id_token_signing_alg_values_supported": [
"HS256",
"RS256"
],
"issuer": JWT_CONFIG['iss'],
"response_types_supported": [
"code",
# TODO check what it takes to support these too
# "id_token",
# "id_token token",
# "code token",
# "code id_token",
# "code id_token token"
],
"subject_types_supported": [
"public"
],
"token_endpoint_auth_methods_supported": [
# TODO is supporting both a good idea? --mh
"client_secret_post",
"client_secret_basic"
],
})
事实证明,实现jwks_uri
端点并不难,它的工作原理大致如下:
def load_public_keys():
public_key_path = Path("etc") / "public.pem"
public_key = JsonWebKey.import_key(public_key_path.read_bytes())
public_key["use"] = "sig"
public_key["alg"] = "RS256"
return KeySet([public_key])
@bp.route("/oauth/jwks")
def jwks_endpoint():
return jsonify(load_public_keys().as_dict())
要让 authlib 使用私钥并设置密钥 id ( kid
),在JWT_CONFIG
JWT_CONFIG = {
"key": "secret-key",
"alg": "RS256",
"iss": "https://sntl-publishing.com",
"exp": 3600,
}
private_key_path = Path('etc') / 'private.pem'
private_key = JsonWebKey.import_key(private_key_path.read_text())
JWT_CONFIG['key'] = KeySet([private_key]).as_dict()
它似乎在 repo 的主版本中已修复,但在当前发布的版本中,您需要as_dict()
调用KeySet
- 否则kid
不是生成的 id 令牌的一部分,客户端将无法使用来自的信息验证它jwks_uri
端点。