使用 python 登录到 SAML/Shibboleth 认证服务器

新手上路,请多包涵

我正在尝试通过 python 登录我大学的服务器,但我完全不确定如何生成适当的 HTTP POST、创建密钥和证书以及我可能不熟悉的过程的其他部分遵守 SAML 规范。我可以很好地使用我的浏览器登录,但我希望能够使用 python 登录和访问服务器中的其他内容。

作为参考, 这里是网站

我尝试使用 mechanize 登录(选择表单、填充字段、通过 mechanize.Broswer.submit() 等单击提交按钮控件)无济于事;登录站点每次都会被吐出来。

在这一点上,我愿意使用最适合该任务的语言来实施解决方案。基本上,我想以编程方式登录到 SAML 身份验证服务器。

原文由 David Perlaza 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 651
2 个回答

基本上您必须了解的是 SAML 身份验证过程背后的工作流程。不幸的是,没有 PDF 似乎真的可以很好地帮助您了解浏览器在访问受 SAML 保护的网站时执行了哪些操作。

也许你应该看看这样的东西:http: //www.docstoc.com/docs/33849977/Workflow-to-Use-Shibboleth-Authentication-to-Sign 显然是这样的: http://en.wikipedia .org/wiki/Security_Assertion_Markup_Language 。特别要注意这个方案:

在此处输入图像描述

当我试图理解 SAML 的工作方式时 由于文档太少,我所做的是写下(是的!写在纸上)浏览器从头到尾执行的所有步骤。我使用 Opera,将其设置为 不允许 自动重定向(300、301、302 响应代码等),并且也不允许启用 Javascript。然后我记下了服务器发送给我的所有 cookie、正在做什么以及出于什么原因。

也许是付出了太多的努力,但通过这种方式,我能够用 Java 编写一个适合这项工作的库,而且速度和效率都令人难以置信。也许有一天我会公开发布它……

您应该了解的是,在 SAML 登录中,有两个角色在起作用:IDP(身份提供者)和 SP(服务提供者)。

A. 第一步:用户代理向 SP 请求资源

我很确定您是从另一个页面点击“访问受保护的网站”之类的内容,到达了您在问题中引用的链接。如果您多加注意,您会注意到您点击的链接 不是 显示身份验证表单的链接。这是因为单击从 IDP 到 SP 的链接是 SAML 的一个 _步骤_。第一步,其实。它允许 IDP 定义您是谁,以及您尝试访问其资源的原因。因此,基本上您需要做的是向您所关注的链接发出请求以访问 Web 表单,并获取它将设置的 cookie。您看不到的是 SAMLRequest 字符串,编码到链接后面的 302 重定向中,发送给建立连接的 IDP。

我认为这就是你不能将整个过程机械化的原因。您只需连接到表格,无需进行身份识别!

B. 第二步:填写表格并提交

这个很简单。请小心! 现在 设置的cookies和上面的cookies不一样。您现在正在连接到一个完全不同的网站。这就是使用 SAML 的原因: _不同的网站,相同的凭据_。因此,您可能希望将成功登录提供的这些身份验证 cookie 存储到不同的变量中。 IDP 现在将向您发回一个响应(在 SAMLRequest 之后):SAMLResponse。您必须检测它获取登录结束的网页的源代码。事实上,这个页面是一个包含响应的大表单,当页面加载时,JS 中的一些代码会自动提交它。您必须获取页面的源代码,解析它以摆脱所有无用的 HTML 内容,并获取 SAMLResponse(加密)。

C. 第三步:将响应发送回 SP

现在您已准备好结束程序。您必须将在上一步中获得的 SAMLResponse 发送(通过 POST,因为您正在模拟表单)到 SP。通过这种方式,它将提供访问您想要访问的受保护内容所需的 cookie。

Aaaaand,你完成了!

同样,我认为您必须做的最宝贵的事情是使用 Opera 并分析 SAML 所做的所有重定向。然后,在您的代码中复制它们。这并不难,请记住 IDP 与 SP 完全不同。

原文由 Gian Segato 发布,翻译遵循 CC BY-SA 4.0 许可协议

带有无头 PhantomJS webkit 的 Selenium 将是您登录 Shibboleth 的最佳选择,因为它可以为您处理 cookie 甚至 Javascript。

安装:

 $ pip install selenium
$ brew install phantomjs

 from selenium import webdriver
from selenium.webdriver.support.ui import Select # for <SELECT> HTML form

driver = webdriver.PhantomJS()
# On Windows, use: webdriver.PhantomJS('C:\phantomjs-1.9.7-windows\phantomjs.exe')

# Service selection
# Here I had to select my school among others
driver.get("http://ent.unr-runn.fr/uPortal/")
select = Select(driver.find_element_by_name('user_idp'))
select.select_by_visible_text('ENSICAEN')
driver.find_element_by_id('IdPList').submit()

# Login page (https://cas.ensicaen.fr/cas/login?service=https%3A%2F%2Fshibboleth.ensicaen.fr%2Fidp%2FAuthn%2FRemoteUser)
# Fill the login form and submit it
driver.find_element_by_id('username').send_keys("myusername")
driver.find_element_by_id('password').send_keys("mypassword")
driver.find_element_by_id('fm1').submit()

# Now connected to the home page
# Click on 3 links in order to reach the page I want to scrape
driver.find_element_by_id('tabLink_u1240l1s214').click()
driver.find_element_by_id('formMenu:linknotes1').click()
driver.find_element_by_id('_id137Pluto_108_u1240l1n228_50520_:tabledip:0:_id158Pluto_108_u1240l1n228_50520_').click()

# Select and print an interesting element by its ID
page = driver.find_element_by_id('_id111Pluto_108_u1240l1n228_50520_:tableel:tbody_element')
print page.text

笔记:

  • 在开发过程中,使用 Firefox 预览你在做什么 driver = webdriver.Firefox()
  • 该脚本按原样提供并带有相应的链接,因此您可以将每一行代码与页面的实际源代码进行比较(至少在登录之前)。

原文由 Stéphane Bruckert 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏