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

如何编程实现Azure AD认证内网后自动下载SAML SSO外部站点文件

实现从外部站点自动下载文件的分步方案

Great question—this is a super common scenario when automating enterprise workflows that involve layered SSO and Azure AD. Let’s break down how to pull this off, with two reliable approaches depending on your needs.

方案一:浏览器自动化(最贴近手动流程,适合复杂认证)

If your workflow involves tricky frontend rendering, MFA prompts, or hard-to-reverse-engineer SAML jumps, browser automation is your best bet. Tools like Playwright, Puppeteer, or Selenium mimic human browser actions, so they handle all the redirects and session management automatically.

具体步骤:

  • 初始化浏览器实例:生产环境用无头模式,调试时用可视模式,同时开启下载自动处理。
  • 模拟Azure AD登录:填写账号密码,或处理MFA提示(比如让用户扫码一次,或用设备代码流实现完全自动化)。
  • 导航到外部站点入口:点击内网门户上的外部站点链接,或直接访问触发SAML跳转的URL。
  • 等待SSO完成:浏览器会自动跟随所有SAML请求/响应的重定向,完成外部站点的登录。
  • 触发并保存下载:定位下载按钮/链接,点击后配置工具将文件保存到指定目录。

Playwright示例代码(Python):

from playwright.sync_api import sync_playwright
import time

with sync_playwright() as p:
    # 启动浏览器(生产环境用headless=True)
    browser = p.chromium.launch(headless=False)
    context = browser.new_context(accept_downloads=True)
    page = context.new_page()

    # 1. 访问内网站点登录页
    page.goto("https://your-internal-site.com/login")

    # 2. 完成Azure AD登录(根据你的租户登录页更新选择器)
    page.fill("#i0116", "your-username@company.com")
    page.click("#idSIButton9")
    page.fill("#i0118", "your-secure-password")
    page.click("#idSIButton9")

    # 处理MFA(比如等待用户扫码,超时时间设为60秒)
    # page.wait_for_url("https://your-internal-site.com/dashboard", timeout=60000)

    # 3. 通过内网门户导航到外部站点
    page.click("text=Access External Document Site")
    # 或者直接使用已知的SAML跳转URL:
    # page.goto("https://your-internal-site.com/saml/redirect/external-service")

    # 4. 等待SSO完成并进入外部站点
    page.wait_for_url("https://external-site.com/home")

    # 5. 触发下载并保存文件
    with page.expect_download() as download_info:
        page.click("text=Download Report")
    download = download_info.value
    download.save_as("./automated-download.pdf")

    print(f"Success! File saved to: {download.path()}")
    browser.close()

方案二:纯API模拟(更高效,适合可逆向的流程)

如果你能逆向分析手动流程中的HTTP请求,这种方法更轻量、更快(无需浏览器)。你可以用HTTP客户端模拟认证链的每一步。

具体步骤:

  • 获取Azure AD访问令牌:使用Microsoft认证库(MSAL)获取内网站点的访问令牌。用户专属访问推荐用授权码流(优先选择),如果无MFA且安全允许,也可以用用户名密码流。
  • 建立内网站点会话:用Azure AD令牌向内网站点认证,获取会话Cookie。
  • 获取并提交SAML断言:触发内网站点的SAML请求,捕获编码后的SAML响应,然后POST到外部站点的断言消费服务(ACS)端点。
  • 下载文件:使用外部站点的会话Cookie访问下载URL,将响应内容保存到本地文件。

API示例代码(Python + MSAL + Requests):

import msal
import requests

# 步骤1:获取Azure AD访问令牌
CLIENT_ID = "your-internal-site-aad-client-id"
TENANT_ID = "your-azure-ad-tenant-id"
USERNAME = "your-username@company.com"
PASSWORD = "your-secure-password"
SCOPES = ["https://your-internal-site.com/api/user.read"]

app = msal.PublicClientApplication(CLIENT_ID, authority=f"https://login.microsoftonline.com/{TENANT_ID}")
result = app.acquire_token_by_username_password(USERNAME, PASSWORD, scopes=SCOPES)

if "access_token" not in result:
    raise Exception(f"Token fetch failed: {result.get('error')} - {result.get('error_description')}")
access_token = result["access_token"]

# 步骤2:认证内网站点并获取会话Cookie
session = requests.Session()
auth_headers = {"Authorization": f"Bearer {access_token}"}
response = session.get("https://your-internal-site.com/api/auth/validate", headers=auth_headers)
response.raise_for_status()

# 步骤3:触发SAML重定向并捕获断言
# (需要抓包获取准确的SAML端点和参数)
saml_redirect_response = session.get("https://your-internal-site.com/saml/init/external-site")
saml_redirect_response.raise_for_status()

# 从响应中提取SAMLResponse和ACS URL(可使用BeautifulSoup解析页面)
acs_url = "https://external-site.com/saml/acs"
saml_response = "base64-encoded-saml-assertion-from-internal-site"

# 提交SAML响应到外部站点
saml_payload = {
    "SAMLResponse": saml_response,
    "RelayState": "optional-relay-state-value"
}
acs_response = session.post(acs_url, data=saml_payload)
acs_response.raise_for_status()

# 步骤4:下载文件
download_response = session.get("https://external-site.com/download/report.pdf")
download_response.raise_for_status()

with open("./api-downloaded-report.pdf", "wb") as f:
    f.write(download_response.content)

print("File downloaded successfully via API!")

关键注意事项

  • MFA处理:如果Azure AD租户要求MFA,浏览器自动化可能需要用户手动输入(比如扫码),除非你为服务主体使用Azure AD的设备代码流。
  • SAML元数据:如果能获取内网站点(IDP)和外部站点(SP)的SAML元数据,会大幅简化SAML请求的逆向分析。
  • 安全最佳实践:绝对不要硬编码凭证,使用环境变量或Azure Key Vault等密钥管理器存储敏感信息。除非必要,避免使用用户名密码流。
  • 会话持久化:可以将会话Cookie保存到文件,避免每次都重新认证,但要注意处理Cookie过期和安全存储。

内容的提问来源于stack exchange,提问作者yogesh.tewari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:28:41