Python Requests+MSAL访问Azure SAML保护URL返回登录页问题
问题排查与解决方案
核心问题:Token 作用域不匹配
你当前获取的 access_token 是针对Microsoft Graph API的(因为 scope 设置为 ['User.Read'],这是 Graph 的专属权限),但目标爬取的网站是受 Azure SAML 保护的独立应用,这个 Token 对它完全无效,因此会返回 SAML 登录页。而调用 Graph 接口正常,正是因为 Token 本身就是为 Graph 生成的。
具体解决步骤
1. 确认目标网站的应用注册信息
- 登录 Azure AD 后台,找到目标网站对应的应用注册,获取它的应用 ID URI(通常格式类似
https://your-company.com/target-app)。 - 确认该应用支持的权限范围:如果是自定义权限,格式为
{应用ID URI}/.default;如果是内置权限,需从应用注册的权限列表中获取具体值。
2. 修改 Scope 参数,生成目标网站的 Token
将代码中的 scope 替换为目标网站对应的权限范围,示例如下:
# 替换为目标网站的应用ID URI + /.default scope = ["https://your-target-app-uri.com/.default"]
说明:
/.default范围会请求该应用注册中已配置的所有静态权限,适合当前使用的用户名密码流(ROPC)场景。
3. 验证 Token 的受众是否正确
获取 Token 后,可通过解码 Token 查看内容,重点检查 aud(受众)字段是否为目标网站的应用 ID 或应用 ID URI,确保 Token 是颁发给目标应用的。
4. 适配目标网站的认证方式
部分 SAML 保护的网站不直接支持 Bearer Token 认证,需要通过 SAML 断言完成登录流程:
- 先通过 MSAL 获取 SAML 断言
- 将断言提交到网站的 SAML 登录端点,获取会话 Cookie 后再发起请求
示例代码:
# 获取目标应用的SAML断言 result = app.acquire_token_by_username_password( username=user, password=pwd, scopes=["https://your-target-app-uri.com/.default"], resource="https://your-target-app-uri.com" ) # 目标网站的SAML登录端点(需根据实际情况替换) login_url = "https://my web site where i need to do crawling/saml/login" # 构造SAML提交表单 form_data = { "SAMLResponse": result.get("saml_token"), "RelayState": "/" } # 使用Session维持会话,提交断言获取Cookie session = requests.Session() session.post(login_url, data=form_data, proxies=proxyDict) # 用已认证的Session访问目标页面 response = session.get(url, proxies=proxyDict)
5. 检查代理是否干扰认证
确认代理没有修改请求头中的 Authorization 字段,部分代理会过滤或重写 Bearer Token 头导致认证失败。可通过打印请求头或启用调试日志验证:
print(api_head) # 启用调试日志查看实际发送的请求头 import logging logging.basicConfig(level=logging.DEBUG)
内容的提问来源于stack exchange,提问作者om tripathi
相关产品推荐
相关产品推荐

