🔍 Code Extractor

function setup_azure_sso

Maturity: 51

Initializes and configures an Azure SSO (Single Sign-On) instance by retrieving credentials from environment variables or settings, with fallback to MS365 configuration values.

File:
/tf/active/vicechatdev/CDocs/auth/azure_auth.py
Lines:
127 - 194
Complexity:
moderate

Purpose

This function sets up Azure Active Directory authentication for a Flask application by gathering required OAuth2 credentials (client ID, tenant ID, client secret, redirect URI, and scope) from multiple sources in priority order: environment variables, application settings, and MS365 fallback settings. It returns a configured AzureSSO instance ready for authentication flows, or None if required configuration is missing. The function includes comprehensive logging for debugging authentication setup issues.

Source Code

def setup_azure_sso():
    """
    Set up Azure SSO with configuration from environment variables or settings.
    
    Returns:
        AzureSSO: Configured AzureSSO instance or None if configuration is missing
    """
    try:
        from CDocs.config import settings
        
        client_id = os.getenv('AZURE_CLIENT_ID', getattr(settings, 'AZURE_CLIENT_ID', None))
        tenant_id = os.getenv('AZURE_TENANT_ID', getattr(settings, 'AZURE_TENANT_ID', None))
        client_secret = os.getenv('AZURE_CLIENT_SECRET', getattr(settings, 'AZURE_CLIENT_SECRET', None))
        redirect_uri = os.getenv('FLASK_AZURE_REDIRECT_URI', 
                                os.getenv('AZURE_REDIRECT_URI', 
                                         getattr(settings, 'FLASK_AZURE_REDIRECT_URI',
                                                getattr(settings, 'AZURE_REDIRECT_URI', None))))
        scope = os.getenv('AZURE_SCOPE', getattr(settings, 'AZURE_SCOPE', 'openid profile email User.Read'))
        
        # Add detailed debugging
        logger.debug(f"Azure SSO configuration from settings/env: Client ID exists: {client_id is not None}, "
                   f"Tenant ID exists: {tenant_id is not None}, "
                   f"Client Secret exists: {client_secret is not None}, "
                   f"Redirect URI: {redirect_uri}")
        
        # Try to use values from MS365 settings if specific Azure SSO settings are not defined
        if not client_id:
            client_id = getattr(settings, 'MS365_CLIENT_ID', None)
            if client_id:
                logger.info("Using MS365_CLIENT_ID for Azure SSO")
                
        if not tenant_id:
            tenant_id = getattr(settings, 'MS365_TENANT_ID', None)
            if tenant_id:
                logger.info("Using MS365_TENANT_ID for Azure SSO")
                
        if not client_secret:
            client_secret = getattr(settings, 'MS365_CLIENT_SECRET', None)
            if client_secret:
                logger.info("Using MS365_CLIENT_SECRET for Azure SSO")
        
        # More detailed debugging after fallbacks
        logger.debug(f"Azure SSO configuration after MS365 fallbacks: Client ID exists: {client_id is not None}, "
                   f"Tenant ID exists: {tenant_id is not None}, "
                   f"Client Secret exists: {client_secret is not None}, "
                   f"Redirect URI: {redirect_uri}")
                   
        if not all([client_id, tenant_id, client_secret, redirect_uri]):
            logger.warning("Azure SSO configuration is incomplete. "
                          f"Client ID exists: {client_id is not None}, "
                          f"Tenant ID exists: {tenant_id is not None}, "
                          f"Client Secret exists: {'Yes' if client_secret else 'No'}, "
                          f"Redirect URI exists: {redirect_uri is not None}")
            return None
            
        return AzureSSO(
            client_id=client_id,
            tenant_id=tenant_id,
            client_secret=client_secret,
            redirect_uri=redirect_uri,
            scope=scope
        )
    except ImportError:
        logger.error("Could not import settings module")
        return None
    except Exception as e:
        logger.error(f"Error setting up Azure SSO: {e}")
        return None

Return Value

Returns an AzureSSO instance configured with client_id, tenant_id, client_secret, redirect_uri, and scope if all required credentials are found. Returns None if any required configuration is missing, if the settings module cannot be imported, or if any exception occurs during setup. The AzureSSO instance can be used to initiate OAuth2 authentication flows with Azure Active Directory.

Dependencies

  • os
  • logging
  • CDocs.config
  • msal

Required Imports

import os
import logging

Conditional/Optional Imports

These imports are only needed under specific conditions:

from CDocs.config import settings

Condition: Required to access application settings; imported inside try block to handle ImportError gracefully

Required (conditional)

Usage Example

import os
import logging

# Configure logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

# Set required environment variables
os.environ['AZURE_CLIENT_ID'] = 'your-client-id-here'
os.environ['AZURE_TENANT_ID'] = 'your-tenant-id-here'
os.environ['AZURE_CLIENT_SECRET'] = 'your-client-secret-here'
os.environ['FLASK_AZURE_REDIRECT_URI'] = 'https://yourapp.com/auth/callback'

# Optional: Set custom scope
os.environ['AZURE_SCOPE'] = 'openid profile email User.Read'

# Setup Azure SSO
azure_sso = setup_azure_sso()

if azure_sso:
    print("Azure SSO configured successfully")
    # Use azure_sso for authentication flows
else:
    print("Azure SSO configuration failed - check logs for details")

Best Practices

  • Ensure all required environment variables or settings are configured before calling this function
  • Store sensitive credentials (client_secret) in environment variables rather than hardcoding in settings files
  • Check the return value for None before using the AzureSSO instance
  • Review application logs at DEBUG level to troubleshoot configuration issues
  • The function provides fallback to MS365 settings, so either Azure-specific or MS365 credentials can be used
  • Redirect URI must match exactly what is configured in Azure AD application registration
  • The default scope 'openid profile email User.Read' is suitable for basic user authentication; adjust if additional permissions are needed
  • Ensure the AzureSSO class is properly defined and imported in the module before calling this function
  • Handle the None return value gracefully in production code to prevent authentication failures

Similar Components

AI-powered semantic similarity - components with related functionality:

  • function setup_azure_sso_v1 81.4% similar

    Initializes and configures an Azure SSO (Single Sign-On) instance by loading credentials and settings from a configuration module.

    From: /tf/active/vicechatdev/docchat/auth/azure_auth.py
  • function auth_callback 68.8% similar

    OAuth callback handler that processes Azure SSO authentication responses, exchanges authorization codes for access tokens, and establishes user sessions.

    From: /tf/active/vicechatdev/vice_ai/complex_app.py
  • function auth_callback_v1 65.3% similar

    OAuth2 callback handler for Azure SSO authentication that processes authorization codes, exchanges them for access tokens, and establishes user sessions.

    From: /tf/active/vicechatdev/vice_ai/new_app.py
  • function auth_callback_v2 65.0% similar

    Flask route handler that processes OAuth 2.0 callback from Azure AD, exchanges authorization code for access tokens, and establishes user session.

    From: /tf/active/vicechatdev/vice_ai/app.py
  • class AzureSSO 64.2% similar

    A class that handles Azure Active Directory (Azure AD) Single Sign-On (SSO) authentication using OAuth 2.0 authorization code flow.

    From: /tf/active/vicechatdev/docchat/auth/azure_auth.py
← Back to Browse