From 172d1bee15fadf829dc46ab71d64393eeeff7f86 Mon Sep 17 00:00:00 2001 From: kaiyou <pierre@jaury.eu> Date: Wed, 10 Jun 2020 10:40:34 +0200 Subject: [PATCH] Switch to RSA signature for id tokens --- hiboo/sso/oidc.py | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/hiboo/sso/oidc.py b/hiboo/sso/oidc.py index fb8cb68d..b9aab897 100644 --- a/hiboo/sso/oidc.py +++ b/hiboo/sso/oidc.py @@ -8,8 +8,9 @@ from authlib.integrations import flask_oauth2, sqla_oauth2 from authlib.oauth2 import rfc6749 as oauth2 from authlib.oidc import core as oidc from authlib.common import security as authlib_security +from authlib.jose import jwk -from hiboo.sso import blueprint, get_service +from hiboo.sso import blueprint, get_service, generate_rsa_certificate from hiboo import models, utils, profile, security import flask @@ -17,15 +18,23 @@ import time import inspect +RSA_KEY_LENGTH = 2048 + + def fill_service(service): """ If necessary, prepare the client with cryptographic material. """ if "client_id" not in service.config: service.config.update( client_id=authlib_security.generate_token(24), - client_secret=authlib_security.generate_token(48), - jwt_key=authlib_security.generate_token(24), - jwt_alg="HS256" + client_secret=authlib_security.generate_token(48) + ) + if "jwt_public_key" not in service.config: + key, public, _ = generate_rsa_certificate(service.uuid) + service.config.update( + jwt_key=jwk.dumps(key, kty="RSA"), + jwt_public_key=jwk.dumps(public, kty="RSA"), + jwt_alg="RS256" ) @@ -173,12 +182,16 @@ class Client(sqla_oauth2.OAuth2ClientMixin): "authorization_endpoint": flask.url_for("sso.oidc_authorize", service_uuid=uuid, _external=True), "token_endpoint": flask.url_for("sso.oidc_token", service_uuid=uuid, _external=True), "userinfo_endpoint": flask.url_for("sso.oidc_userinfo", service_uuid=uuid, _external=True), + "jwks_uri": flask.url_for("sso.oidc_jwks", service_uuid=uuid, _external=True), "response_types_supported": " ".join(self.service.config["response_types"]), "subject_types_supported": ["pairwise"], "id_token_signing_alg_values_supported": ["none"], "claims_supported": ["openid", "profile", "email"] }) + def generate_jwks(self): + return flask.jsonify({"keys": [self.service.config["jwt_public_key"]]}) + @blueprint.route("/oidc/authorize/<service_uuid>", methods=["GET", "POST"]) @blueprint.route("/oidc/<service_uuid>/authorize", methods=["GET", "POST"]) @@ -205,6 +218,12 @@ def oidc_userinfo(service_uuid): return client.generate_user_info(profile, token["scope"]) +@blueprint.route("/oidc/<service_uuid>/jwks", methods=["GET"]) +def oidc_jwks(service_uuid): + client = Client(get_service(service_uuid, __name__)) + return client.generate_jwks() + + @blueprint.route("/oidc/<service_uuid>/.well-known/openid-configuration", methods=["GET"]) def oidc_discovery(service_uuid): client = Client(get_service(service_uuid, __name__)) -- GitLab