Loading src/common/auth.py +81 −0 Original line number Diff line number Diff line """Provide authentication methods.""" from urllib.parse import urlparse, urlencode from common.env import check_environment as ce try: Loading Loading @@ -56,3 +57,83 @@ def authenticate_ldap_user(uid, password): return None connection.search(root_dn, user_search_filter, attributes=["*"]) return connection.entries[0] def authenticate_saml( scheme, host, url, method, args, form, process_success=lambda _: None, process_failure=lambda _: None, saml_path=None, ): """ Handles SAML authentication by processing the necessary components extracted from a web request. This function manages SAML Single Sign-On (SSO), Single Log-Out (SLO), and Assertion Consumer Service (ACS) endpoints. It accepts individual components typically found in a web request and utilizes them to process SAML requests and responses, delegating outcome handling to provided callback functions. Parameters: - scheme (str): The request scheme ('http' or 'https'). - host (str): The request host. - url (str): The full URL of the request. - method (str): The HTTP method of the request. - args (dict): The query parameters of the request as a dictionary. - form (dict): The form data of the request as a dictionary. - process_success (Callable): Function to call after successful authentication or logout to handle the response. - process_failure (Callable): Function to call when an error occurs or no relevant SAML action is found. - saml_path (str, optional): Custom path for SAML configuration files. If not provided, environment variable 'SAML_PATH' is used. Returns: - Result of the `process_success` or `process_failure` callable depending on the SAML processing outcome. Raises: - Exception: Descriptive exceptions can be raised depending on the SAML processing errors or misconfigurations. Usage: This function is designed to be framework-agnostic and should be integrated into any web application by adapting the request handling to extract necessary components. Example: # Extract necessary components from a Flask or Django request and pass them to this function. result = authenticate_saml(request.scheme, request.host, request.url, request.method, request.args, request.form, handle_success, handle_failure) """ # Prepare request data for SAML auth url_data = urlparse(url) saml_request = { "https": "on" if scheme == "https" else "off", "http_host": host, "server_port": url_data.port, "script_name": url_data.path, "get_data": args, "post_data": form, "query_string": urlencode(args) if method == "GET" else "", } # Initialize SAML auth saml_path = saml_path or ce("SAML_PATH") auth = OneLogin_Saml2_Auth(saml_request, custom_base_path=saml_path) # SAML Action Handling try: if "sso" in args: return process_success(auth.login()) elif "slo" in args: return process_success(auth.logout()) elif "acs" in args: auth.process_response( request_id=None ) # Assuming request carries all needed info if auth.is_authenticated(): return process_success(None) # pass user details / attributes else: return process_failure("Authentication failed or errors occurred") else: return process_failure("No SAML action found") except Exception as e: return process_failure(str(e)) Loading
src/common/auth.py +81 −0 Original line number Diff line number Diff line """Provide authentication methods.""" from urllib.parse import urlparse, urlencode from common.env import check_environment as ce try: Loading Loading @@ -56,3 +57,83 @@ def authenticate_ldap_user(uid, password): return None connection.search(root_dn, user_search_filter, attributes=["*"]) return connection.entries[0] def authenticate_saml( scheme, host, url, method, args, form, process_success=lambda _: None, process_failure=lambda _: None, saml_path=None, ): """ Handles SAML authentication by processing the necessary components extracted from a web request. This function manages SAML Single Sign-On (SSO), Single Log-Out (SLO), and Assertion Consumer Service (ACS) endpoints. It accepts individual components typically found in a web request and utilizes them to process SAML requests and responses, delegating outcome handling to provided callback functions. Parameters: - scheme (str): The request scheme ('http' or 'https'). - host (str): The request host. - url (str): The full URL of the request. - method (str): The HTTP method of the request. - args (dict): The query parameters of the request as a dictionary. - form (dict): The form data of the request as a dictionary. - process_success (Callable): Function to call after successful authentication or logout to handle the response. - process_failure (Callable): Function to call when an error occurs or no relevant SAML action is found. - saml_path (str, optional): Custom path for SAML configuration files. If not provided, environment variable 'SAML_PATH' is used. Returns: - Result of the `process_success` or `process_failure` callable depending on the SAML processing outcome. Raises: - Exception: Descriptive exceptions can be raised depending on the SAML processing errors or misconfigurations. Usage: This function is designed to be framework-agnostic and should be integrated into any web application by adapting the request handling to extract necessary components. Example: # Extract necessary components from a Flask or Django request and pass them to this function. result = authenticate_saml(request.scheme, request.host, request.url, request.method, request.args, request.form, handle_success, handle_failure) """ # Prepare request data for SAML auth url_data = urlparse(url) saml_request = { "https": "on" if scheme == "https" else "off", "http_host": host, "server_port": url_data.port, "script_name": url_data.path, "get_data": args, "post_data": form, "query_string": urlencode(args) if method == "GET" else "", } # Initialize SAML auth saml_path = saml_path or ce("SAML_PATH") auth = OneLogin_Saml2_Auth(saml_request, custom_base_path=saml_path) # SAML Action Handling try: if "sso" in args: return process_success(auth.login()) elif "slo" in args: return process_success(auth.logout()) elif "acs" in args: auth.process_response( request_id=None ) # Assuming request carries all needed info if auth.is_authenticated(): return process_success(None) # pass user details / attributes else: return process_failure("Authentication failed or errors occurred") else: return process_failure("No SAML action found") except Exception as e: return process_failure(str(e))