You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python实现Cisco Webex基于ADFS的SSO客户端认证?

Hey there, I get exactly what you're asking for—you want to simulate a browser-like SSO client authentication flow for Webex (using your existing ADFS setup), not set up a Service Provider (SP) for SSO. Most tutorials online focus on the SP side, so it's totally understandable why you're stuck. Let me break down the feasible approaches and share some example code:

Core Implementation Directions

You have two main paths here, depending on how much control/lightweight you need your solution to be:

  • Browser Automation (Simpler, but heavier):Use tools like Playwright or Selenium to replicate exactly what a Chrome user does—clicking, typing, and following redirects. This avoids manually handling all the messy HTTP details like dynamic tokens or cookies.
  • Manual HTTP Request Replication (Lightweight, but requires packet capture):Use the requests library to mimic the HTTP flow you capture from Chrome's DevTools. You'll need to record all redirects, form parameters, and cookies to replicate the login sequence accurately.

Playwright is a modern browser automation tool that's more intuitive than Selenium, and it supports headless mode if you don't need a visible browser.

Step 1: Install Dependencies

pip install playwright
playwright install chrome

Step 2: Example Code

from playwright.sync_api import sync_playwright
import json

def webex_sso_login(webex_portal_url, adfs_username, adfs_password):
    with sync_playwright() as p:
        # Launch Chrome (set headless=True for invisible mode)
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        
        # Navigate to Webex portal—this will auto-redirect to ADFS login page
        page.goto(webex_portal_url)
        
        # Wait for ADFS login form to load, then input credentials
        page.wait_for_selector('#userNameInput', timeout=30000)
        page.fill('#userNameInput', adfs_username)
        page.fill('#passwordInput', adfs_password)
        page.click('#submitButton')
        
        # Wait for redirect back to Webex and confirm authentication
        page.wait_for_url('https://*.webex.com/*', timeout=60000)
        
        # Extract Webex access token (from LocalStorage—adjust based on your environment)
        access_token = page.evaluate("localStorage.getItem('access_token')")
        print(f"Successfully retrieved Webex Access Token: {access_token}")
        
        # Save cookies for future API calls (optional)
        cookies = page.context.cookies()
        with open('webex_auth_cookies.json', 'w') as f:
            json.dump(cookies, f)
        
        browser.close()
        return access_token

# Run the login flow
if __name__ == "__main__":
    WEBEX_URL = "https://your-company-webex-portal.com"
    ADFS_USER = "your-adfs-username@company.com"
    ADFS_PASS = "your-adfs-password"
    webex_sso_login(WEBEX_URL, ADFS_USER, ADFS_PASS)

Solution 2: Manual HTTP Flow with requests

This approach is lighter but requires you to capture the exact login sequence using Chrome DevTools (Network tab). You'll need to note redirect URLs, form parameters, and dynamic tokens like CSRF or __VIEWSTATE.

Example Code (Adjust Based on Your ADFS/Webex Setup)

import requests
from bs4 import BeautifulSoup

def webex_sso_login_manual(webex_portal_url, adfs_username, adfs_password):
    session = requests.Session()
    
    # Step 1: Access Webex, get redirect to ADFS
    initial_resp = session.get(webex_portal_url)
    soup = BeautifulSoup(initial_resp.text, 'html.parser')
    adfs_form = soup.find('form', {'action': lambda x: x and 'adfs' in x.lower()})
    if not adfs_form:
        raise Exception("Couldn't find ADFS redirect form")
    
    adfs_login_url = adfs_form['action']
    # Extract hidden form fields (SAMLRequest, RelayState, etc.)
    form_data = {
        input_tag['name']: input_tag.get('value', '') 
        for input_tag in adfs_form.find_all('input', {'name': True})
    }
    
    # Step 2: Submit to ADFS, load login page
    adfs_resp = session.post(adfs_login_url, data=form_data)
    soup = BeautifulSoup(adfs_resp.text, 'html.parser')
    login_form = soup.find('form', id='loginForm')
    if not login_form:
        raise Exception("Couldn't find ADFS login form")
    
    login_submit_url = login_form['action']
    # Prepare login data with dynamic tokens
    login_data = {
        'UserName': adfs_username,
        'Password': adfs_password,
        'AuthMethod': 'FormsAuthentication',
        '__VIEWSTATE': soup.find('input', {'name': '__VIEWSTATE'})['value'],
        '__EVENTVALIDATION': soup.find('input', {'name': '__EVENTVALIDATION'})['value']
    }
    
    # Step 3: Submit credentials to ADFS
    mfa_resp = session.post(login_submit_url, data=login_data)
    soup = BeautifulSoup(mfa_resp.text, 'html.parser')
    
    # Step 4: Submit SAML response back to Webex (auto-generated form)
    saml_form = soup.find('form', {'action': lambda x: x and 'webex' in x.lower()})
    if not saml_form:
        raise Exception("Couldn't find Webex SAML callback form")
    
    saml_data = {
        input_tag['name']: input_tag.get('value', '') 
        for input_tag in saml_form.find_all('input', {'name': True})
    }
    final_resp = session.post(saml_form['action'], data=saml_data)
    
    # Extract access token from cookies (adjust based on Webex's auth mechanism)
    access_token = session.cookies.get('access_token')
    print(f"Successfully retrieved Webex Access Token: {access_token}")
    
    return access_token

# Run the manual flow (update parameters based on your capture)
if __name__ == "__main__":
    WEBEX_URL = "https://your-company-webex-portal.com"
    ADFS_USER = "your-adfs-username@company.com"
    ADFS_PASS = "your-adfs-password"
    webex_sso_login_manual(WEBEX_URL, ADFS_USER, ADFS_PASS)

Key Notes
  • Dynamic Tokens: ADFS uses dynamic fields like __VIEWSTATE and __EVENTVALIDATION—always extract these from the current page, never hardcode them.
  • MFA Handling: If your ADFS requires multi-factor authentication, Playwright can wait for user input (e.g., SMS code), while the manual approach will need additional steps to capture the MFA flow.
  • API Usage: Once you have the access_token, you can call Webex APIs by adding it to the Authorization header:
    def get_webex_meetings(access_token):
        headers = {'Authorization': f'Bearer {access_token}'}
        resp = requests.get('https://webexapis.com/v1/meetings', headers=headers)
        return resp.json()
    

内容的提问来源于stack exchange,提问作者Difan Zhao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:56:18