如何通过代码发起POST请求提交受Shibboleth保护的网页
解决Shibboleth认证后发起POST请求的问题
你的推测是正确的:通过Shibboleth认证后,服务器会通过会话Cookie标识已认证状态,后续请求只要携带该Cookie就能绕过认证校验,直接提交POST请求。以下是具体实现步骤(以Python requests库为例):
1. 初始化会话,捕获Shibboleth认证入口
先用会话对象访问目标POST地址,触发Shibboleth重定向逻辑,拿到包含SAML请求的页面:
import requests from bs4 import BeautifulSoup # 初始化会话,自动管理Cookie session = requests.Session() target_post_url = "https://www.mywebserver.org:443/web/area/find-product" # 访问目标地址,触发认证重定向 response = session.get(target_post_url) soup = BeautifulSoup(response.text, "html.parser") # 提取页面中的SAML Request(如果已经手动收集好,这步可跳过) saml_request = soup.find("input", {"name": "SAMLRequest"})["value"] idp_login_url = soup.find("form")["action"]
2. 提交认证信息到IDP,获取会话Cookie
向Shibboleth IDP的登录地址提交用户名、密码和短信验证码,认证成功后会话对象会自动保存认证后的Cookie:
# 构造IDP登录参数(参数名需根据实际IDP页面调整) login_payload = { "j_username": "你的用户名", "j_password": "你的密码", "sms_code": "收到的短信验证码", "SAMLRequest": saml_request, "RelayState": soup.find("input", {"name": "RelayState"})["value"] } # 提交认证请求 auth_response = session.post(idp_login_url, data=login_payload) # 校验认证结果:可通过响应内容或状态码判断 if auth_response.status_code == 200 and "产品查询" in auth_response.text: print("认证成功") else: print("认证失败,请检查参数")
3. 携带认证Cookie发起目标POST请求
认证完成后,直接用同一个会话对象发起POST请求,会话会自动携带认证Cookie:
# 构造目标POST的表单参数(和浏览器提交的参数一致) post_payload = { "product_name": "测试产品", "category": "电子设备", # 其他表单参数... } # 发起POST请求 final_response = session.post(target_post_url, data=post_payload) # 处理响应结果 print(final_response.text)
关键注意事项
- 全程必须使用同一个
requests.Session()对象,确保Cookie在请求间一致。 - IDP的登录参数名(如
j_username)可能因配置不同变化,需要抓包浏览器登录请求确认。 - 短信验证码为动态生成,需手动输入或集成第三方短信接收服务,无法完全自动化。
内容的提问来源于stack exchange,提问作者Mauro Minella
相关产品推荐
相关产品推荐

