diff options
author | Frederick Muriuki Muriithi | 2024-04-22 11:37:36 +0300 |
---|---|---|
committer | Frederick Muriuki Muriithi | 2024-04-22 12:23:08 +0300 |
commit | 23de967334a5f7f2f2daa60884d550e5bd27767e (patch) | |
tree | 68f4b0724f581e56738524623777c5ce497e2ea3 | |
parent | 115d98a1022dc57fee5895ac335c4aca9f7acdf5 (diff) | |
download | gn-auth-23de967334a5f7f2f2daa60884d550e5bd27767e.tar.gz |
Separate clients' keys from authorisation server's key
The authorisation server uses its key to sign any token it generates.
It uses the clients' public keys to validate any assertions it
receives from a client using the client's public key.
-rw-r--r-- | gn_auth/__init__.py | 23 | ||||
-rw-r--r-- | gn_auth/auth/authentication/oauth2/server.py | 4 | ||||
-rw-r--r-- | gn_auth/settings.py | 6 |
3 files changed, 18 insertions, 15 deletions
diff --git a/gn_auth/__init__.py b/gn_auth/__init__.py index 5218673..f7e2620 100644 --- a/gn_auth/__init__.py +++ b/gn_auth/__init__.py @@ -25,8 +25,7 @@ def check_mandatory_settings(app: Flask) -> None: undefined = tuple( setting for setting in ( "SECRET_KEY", "SQL_URI", "AUTH_DB", "AUTH_MIGRATIONS", - "OAUTH2_SCOPE", "SSL_KEY_PAIR_PRIVATE_KEY", - "SSL_KEY_PAIR_PUBLIC_KEY") + "OAUTH2_SCOPE", "SSL_PRIVATE_KEY", "CLIENTS_SSL_PUBLIC_KEYS_DIR") if not ((setting in app.config) and bool(app.config[setting]))) if len(undefined) > 0: raise ConfigurationError( @@ -61,14 +60,18 @@ def load_secrets_conf(app: Flask) -> None: app.config.from_pyfile(secretsfile) -def parse_ssl_key_pair(app): - def __parse_key__(keypathconfig: str, configkey: Optional[str]): - configkey = configkey or keypathconfig - with open(app.config[keypathconfig]) as _sslkey: - app.config[configkey] = JsonWebKey.import_key(_sslkey.read()) +def parse_ssl_public_keys(app): + def __parse_key__(keypath: Path) -> JsonWebKey: + with open(keypath) as _sslkey: + return JsonWebKey.import_key(_sslkey.read()) - __parse_key__("SSL_KEY_PAIR_PUBLIC_KEY", "JWT_PUBLIC_KEY") - __parse_key__("SSL_KEY_PAIR_PRIVATE_KEY", "JWT_PRIVATE_KEY") + key_storage_dir = app.config["CLIENTS_SSL_PUBLIC_KEYS_DIR"] + app.config["SSL_PUBLIC_KEYS"] = { + _key.as_dict()["kid"]: _key for _key in ( + __parse_key__(Path(key_storage_dir).joinpath(key)) + for key in os.listdir(key_storage_dir))} + + app.config["SSL_PRIVATE_KEY"] = __parse_key__(app.config["SSL_PRIVATE_KEY"]) def create_app(config: Optional[dict] = None) -> Flask: """Create and return a new flask application.""" @@ -85,7 +88,7 @@ def create_app(config: Optional[dict] = None) -> Flask: override_settings_with_envvars(app) load_secrets_conf(app) - parse_ssl_key_pair(app) + parse_ssl_public_keys(app) # ====== END: Setup configuration ====== check_mandatory_settings(app) diff --git a/gn_auth/auth/authentication/oauth2/server.py b/gn_auth/auth/authentication/oauth2/server.py index db2a0d5..0669139 100644 --- a/gn_auth/auth/authentication/oauth2/server.py +++ b/gn_auth/auth/authentication/oauth2/server.py @@ -66,7 +66,7 @@ def setup_oauth2_server(app: Flask) -> None: server.register_grant(JWTBearerGrant) server.register_token_generator( "urn:ietf:params:oauth:grant-type:jwt-bearer", - JWTBearerTokenGenerator(app.config["JWT_PRIVATE_KEY"])) + JWTBearerTokenGenerator(app.config["SSL_PRIVATE_KEY"])) # register endpoints server.register_endpoint(RevocationEndpoint) @@ -82,4 +82,4 @@ def setup_oauth2_server(app: Flask) -> None: ## Set up the token validators require_oauth.register_token_validator(BearerTokenValidator()) require_oauth.register_token_validator( - JWTBearerTokenValidator(app.config["JWT_PUBLIC_KEY"])) + JWTBearerTokenValidator(app.config["SSL_PRIVATE_KEY"].get_public_key())) diff --git a/gn_auth/settings.py b/gn_auth/settings.py index 59f3eec..489f72d 100644 --- a/gn_auth/settings.py +++ b/gn_auth/settings.py @@ -29,6 +29,6 @@ CORS_HEADERS = [ "Access-Control-Allow-Credentials" ] -# OpenSSL Key-Pair -SSL_KEY_PAIR_PRIVATE_KEY = "" -SSL_KEY_PAIR_PUBLIC_KEY = "" +# OpenSSL keys +CLIENTS_SSL_PUBLIC_KEYS_DIR = "" # keys from registered clients +SSL_PRIVATE_KEY = "" # authorisation server primary key |