GitHub user cboettcher edited a comment on the discussion: Keycloak auth manager causes long loading times for the webserver
Some additional context from what I've already looked into and thought about: [Here](https://github.com/apache/airflow/blob/b7ea2a6fa5418862b93fcb11c75c02bef0f85c95/providers/keycloak/src/airflow/providers/keycloak/auth_manager/keycloak_auth_manager.py#L273) Is the function that is called for every singel-resource authentication request, and it creates a request to keycloak every time. The [batch function](https://github.com/apache/airflow/blob/b7ea2a6fa5418862b93fcb11c75c02bef0f85c95/providers/keycloak/src/airflow/providers/keycloak/auth_manager/keycloak_auth_manager.py#L309) does not seem to be used much. --- I tried something like this, which seemed to solve the loading time issue, but it kinda ignores the `context attributes` and has no proper caching. ``` class KeycloakAuthManagerPermissions(): """A set of permissions.""" def __init__(self, permissions: dict[str, list[str]]) -> None: self.permissions = permissions def get_permissions(self) -> dict[str, list[str]]: return self.permissions def get_resource_permissions(self, resource_name: str) -> list[str]: return self.permissions.get(resource_name, []) @staticmethod def get_permissions_from_keycloak_string(keycloak_permissions: list[dict[str, str | list[str]]]) -> KeycloakAuthManagerPermissions: formatted_permissions: dict[str, list[str]] = {} for single_permission in keycloak_permissions: resource_name = single_permission.get("rsname") allowed_method_list = single_permission.get("scopes", []) if resource_name and isinstance(resource_name, str) and isinstance(allowed_method_list, list): formatted_permissions[resource_name] = allowed_method_list return KeycloakAuthManagerPermissions(formatted_permissions) ``` ``` def _get_user_perms( self, *, user: KeycloakAuthManagerUser ) -> KeycloakAuthManagerPermissions: #TODO store and cache permissions token properly instead of this dict if self._cached_perms.get(user.get_id()): log.debug(f"Using cached permissions for user {user.get_name()}") else: kc_client = self.get_keycloak_client() permissions = kc_client.uma_permissions(token=user.access_token) log.debug(f"Retrieved fresh permissions of user {user.get_id()}.") self._cached_perms[user.get_id()] = KeycloakAuthManagerPermissions.get_permissions_from_keycloak_string(permissions) return self._cached_perms[user.get_id()] ``` ``` def _is_authorized( self, *, method: ResourceMethod | str, resource_type: KeycloakResource, user: KeycloakAuthManagerUser, resource_id: str | None = None, attributes: dict[str, str | None] | None = None, ) -> bool: permissions = self._get_user_perms(user=user) context_attributes = prune_dict(attributes or {}) if resource_id: context_attributes[RESOURCE_ID_ATTRIBUTE_NAME] = resource_id elif method == "GET": method = "LIST" log.debug(f"Trying to get access to {resource_type.value}-{method} for user {user.get_name()}") return method in permissions.get_resource_permissions(resource_type.value) ``` GitHub link: https://github.com/apache/airflow/discussions/56502#discussioncomment-14643893 ---- This is an automatically sent email for [email protected]. To unsubscribe, please send an email to: [email protected]
