sso: implement RS256 JWT signing algo

master
informatic 2022-04-29 01:08:27 +02:00
parent a57ab99014
commit 576ff1b0ea
4 changed files with 36 additions and 14 deletions

View File

@ -16,12 +16,22 @@ services:
volumes:
- .:/usr/src/app
environment:
- TESTING=1
- TEMPLATES_AUTO_RELOAD=true
- AUTHLIB_INSECURE_TRANSPORT=1
# Set these to your testing LDAP dn/password
- LDAP_BIND_DN
- LDAP_BIND_PASSWORD
# ...or uncomment this to allow any login with some mocked user info
# - TESTING=1
- LOGGING_LEVEL=DEBUG
# Uncomment these to enable proper RSA JWT id_tokens signing
# - JWT_PRIVATE_KEY=private.pem
# - JWT_PUBLIC_KEYS=public.pem,public.pem
# - JWT_ALG=RS256
volumes:
pgdata:

View File

@ -25,14 +25,6 @@ import logging
log = logging.getLogger(__name__)
DUMMY_JWT_CONFIG = {
"key": "secret-key",
"alg": "HS256",
"iss": "https://sso.hackerspace.pl",
"exp": 3600,
}
def exists_nonce(nonce, req):
exists = AuthorizationCode.query.filter_by(
client_id=req.client_id, nonce=nonce
@ -48,7 +40,7 @@ def generate_user_info(user, scope):
preferred_username=user.username,
nickname=user.username,
groups=user.groups,
)
)
def create_authorization_code(client, grant_user, request):
@ -116,7 +108,7 @@ class HybridGrant(_OpenIDHybridGrant):
return exists_nonce(nonce, request)
def get_jwt_config(self):
return DUMMY_JWT_CONFIG
return app.config.get("JWT_CONFIG")
def generate_user_info(self, user, scope):
return generate_user_info(user, scope)

View File

@ -51,9 +51,24 @@ LDAP_BIND_PASSWORD = env.str("LDAP_BIND_PASSWORD", default="insert password here
PROXYFIX_ENABLE = env.bool("PROXYFIX_ENABLE", default=True)
PROXYFIX_NUM_PROXIES = env.int("PROXYFIX_NUM_PROXIES", default=1)
import pathlib
from authlib.jose import jwk
jwt_alg = env.str("JWT_ALG", default="HS256")
if jwt_alg == "HS256":
jwt_privkey = env.str("JWT_SECRET_KEY", default=SECRET_KEY)
JWT_PUBLIC_KEYS = []
else:
jwt_privkey = jwk.dumps(env.path("JWT_PRIVATE_KEY").read_text(), kty="RSA")
JWT_PUBLIC_KEYS = [
jwk.dumps(pathlib.Path(pub).read_text(), kty="RSA")
for pub in env.list("JWT_PUBLIC_KEYS")
]
JWT_CONFIG = {
"key": env.str("JWT_SECRET_KEY", default=SECRET_KEY),
"alg": env.str("JWT_ALG", default="HS256"),
"key": jwt_privkey,
"alg": jwt_alg,
"iss": env.str("JWT_ISS", default="https://sso.hackerspace.pl"),
"exp": env.int("JWT_EXP", default=3600),
}

View File

@ -173,7 +173,6 @@ def authorize():
except OAuth2Error as error:
return render_template("authorization_error.html", error=dict(error.get_body()))
print(grant)
if grant.client.membership_required and not current_user.is_membership_active:
return render_template("membership_required.html")
@ -239,6 +238,11 @@ def api_userinfo():
return jsonify(generate_user_info(user, current_token.scope))
@bp.route("/.well-known/jwks.json")
def jwks_endpoint():
return jsonify({"keys": current_app.config["JWT_PUBLIC_KEYS"]})
@bp.route("/.well-known/openid-configuration")
def openid_configuration():
return jsonify(
@ -247,6 +251,7 @@ def openid_configuration():
"authorization_endpoint": url_for(".authorize", _external=True),
"token_endpoint": url_for(".issue_token", _external=True),
"userinfo_endpoint": url_for(".api_userinfo", _external=True),
"jwks_uri": url_for(".jwks_endpoint", _external=True),
"response_types_supported": ["code", "id_token", "token id_token"],
"token_endpoint_auth_methods_supported": [
"client_secret_basic",