From d1560b8018c74fba1498555d81ecb9637a1e9c23 Mon Sep 17 00:00:00 2001 From: shahargl Date: Wed, 16 Apr 2025 17:38:27 +0300 Subject: [PATCH 1/2] fix: keycloak verify bug --- .../keycloak/keycloak_authverifier.py | 29 +++++++++++++++++++ .../keycloak/keycloak_identitymanager.py | 7 +++++ pyproject.toml | 2 +- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/ee/identitymanager/identity_managers/keycloak/keycloak_authverifier.py b/ee/identitymanager/identity_managers/keycloak/keycloak_authverifier.py index 3b974d5217..8c5686d940 100644 --- a/ee/identitymanager/identity_managers/keycloak/keycloak_authverifier.py +++ b/ee/identitymanager/identity_managers/keycloak/keycloak_authverifier.py @@ -6,12 +6,39 @@ from keep.identitymanager.authenticatedentity import AuthenticatedEntity from keep.identitymanager.authverifierbase import AuthVerifierBase, oauth2_scheme from keycloak import KeycloakOpenID, KeycloakOpenIDConnection +from keycloak.connection import ConnectionManager from keycloak.keycloak_uma import KeycloakUMA from keycloak.uma_permissions import UMAPermission logger = logging.getLogger(__name__) +# PATCH TO MONKEYPATCH KEYCLOAK VERIFY BUG +# https://github.com/marcospereirampj/python-keycloak/issues/645 + +original_init = ConnectionManager.__init__ + + +def patched_init( + self, + base_url: str, + headers: dict = None, + timeout: int = 60, + verify: bool = None, + proxies: dict = None, +): + if verify is None: + verify = os.environ.get("KEYCLOAK_VERIFY_CERT", "true").lower() == "true" + logger.warning( + "Using KEYCLOAK_VERIFY_CERT environment variable to set verify. ", + extra={"KEYCLOAK_VERIFY_CERT": verify}, + ) + original_init(self, base_url, headers, timeout, verify, proxies) + + +ConnectionManager.__init__ = patched_init + + class KeycloakAuthVerifier(AuthVerifierBase): """Handles authentication and authorization for Keycloak""" @@ -99,9 +126,11 @@ def _authorize(self, authenticated_entity: AuthenticatedEntity) -> None: resource=self.protected_resource, scope=self.scopes[0], # todo: handle multiple scopes per resource ) + self.logger.info(f"Checking permission {permission}") allowed = self.keycloak_uma.permissions_check( token=authenticated_entity.token, permissions=[permission] ) + self.logger.info(f"Permission check result: {allowed}") if not allowed: raise HTTPException(status_code=401, detail="Permission check failed") # secure fallback diff --git a/ee/identitymanager/identity_managers/keycloak/keycloak_identitymanager.py b/ee/identitymanager/identity_managers/keycloak/keycloak_identitymanager.py index e3f7747623..cd44a37752 100644 --- a/ee/identitymanager/identity_managers/keycloak/keycloak_identitymanager.py +++ b/ee/identitymanager/identity_managers/keycloak/keycloak_identitymanager.py @@ -172,6 +172,13 @@ def _scope_name_to_id(self, all_scopes, scope_name: str) -> str: (scope for scope in all_scopes if scope["name"] == scope_name), None, ) + if not scope: + self.logger.error( + "Scope %s not found in Keycloak", + scope_name, + extra={"scopes": all_scopes}, + ) + return [] return [scope["id"]] def get_permission_by_name(self, permission_name): diff --git a/pyproject.toml b/pyproject.toml index bb2ee67665..572eb0a9c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "keep" -version = "0.41.24" +version = "0.41.25" description = "Alerting. for developers, by developers." authors = ["Keep Alerting LTD"] packages = [{include = "keep"}] From d0b44e9dc202cec6f3b1a20b945c98c4e50265ac Mon Sep 17 00:00:00 2001 From: shahargl Date: Wed, 16 Apr 2025 17:42:15 +0300 Subject: [PATCH 2/2] fix: keycloak verify bug --- .../identity_managers/keycloak/keycloak_authverifier.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ee/identitymanager/identity_managers/keycloak/keycloak_authverifier.py b/ee/identitymanager/identity_managers/keycloak/keycloak_authverifier.py index 8c5686d940..2e7ac6d939 100644 --- a/ee/identitymanager/identity_managers/keycloak/keycloak_authverifier.py +++ b/ee/identitymanager/identity_managers/keycloak/keycloak_authverifier.py @@ -33,6 +33,9 @@ def patched_init( "Using KEYCLOAK_VERIFY_CERT environment variable to set verify. ", extra={"KEYCLOAK_VERIFY_CERT": verify}, ) + + if headers is None: + headers = {} original_init(self, base_url, headers, timeout, verify, proxies)