25

Python 経由で大学のサーバーにログインしようとしていますが、適切な HTTP POST を生成する方法、キーと証明書を作成する方法、および必要なプロセスの他の部分に慣れていない可能性がある方法がまったくわかりません。 SAML 仕様に準拠しています。ブラウザで問題なくログインできますが、Python を使用してサーバー内の他のコンテンツにログインしてアクセスできるようにしたいと考えています。

参考までにサイトはこちら

mechanize を使用してログインしようとしました (フォームの選択、フィールドへの入力、mechanize.Broswer.submit() による送信ボタン コントロールのクリックなど) が役に立ちませんでした。ログインサイトは毎回吐き出されます。

この時点で、タスクに最も適した言語でソリューションを実装することにオープンです。基本的に、プログラムで SAML 認証サーバーにログインしたいと考えています。

4

10 に答える 10

10

ヘッドレス PhantomJS Webkit を備えた Selenium は、Cookie や Javascript を処理するため、Shibboleth にログインするための最善の策です。

インストール:

$ 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()
  • このスクリプトは現状のままで、対応するリンクとともに提供されるため、コードの各行をページの実際のソース コードと比較できます (少なくともログインするまでは)。
于 2014-05-29T09:22:57.097 に答える
2

Shibboleth 認証プロセスの詳細については、こちらを参照してください。

于 2013-11-12T18:08:01.740 に答える
1

大学のページの SAML 認証でも同様の問題に直面しました。

基本的なアイデアは、requests.sessionオブジェクトを使用して、ほとんどの http リダイレクトと Cookie の保存を自動的に処理することです。ただし、両方の JavaScript を使用したリダイレクトも多数あったため、シンプルなリクエスト ソリューションを使用すると複数の問題が発生しました。

私は最終的に、ブラウザが大学のサーバーに行ったすべてのリクエストを追跡するためにフィドラーを使用して、見逃したリダイレクトを埋めました。プロセスが本当に簡単になりました。

私の解決策は理想からはほど遠いですが、うまくいくようです。

于 2016-08-23T23:02:30.173 に答える
1

Javascript を処理しないことを除けば、Mechanize でも同様の作業を行うことができます。認証は正常に機能しましたが、ホームページにアクセスすると、そのようなリンクを読み込めませんでした:

<a href="#" id="formMenu:linknotes1"
   onclick="return oamSubmitForm('formMenu','formMenu:linknotes1');">

Javascript が必要な場合は、PhantomJS で Selenium を使用することをお勧めします。それ以外の場合は、次のスクリプトからインスピレーションを得ていただければ幸いです。

#!/usr/bin/env python
#coding: utf8
import sys, logging
import mechanize
import cookielib
from BeautifulSoup import BeautifulSoup
import html2text

br = mechanize.Browser() # Browser
cj = cookielib.LWPCookieJar() # Cookie Jar
br.set_cookiejar(cj) 

# Browser options
br.set_handle_equiv(True)
br.set_handle_gzip(True)
br.set_handle_redirect(True)
br.set_handle_referer(True)
br.set_handle_robots(False)

# Follows refresh 0 but not hangs on refresh > 0
br.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1)

# User-Agent
br.addheaders = [('User-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36')]

br.open('https://ent.unr-runn.fr/uPortal/')
br.select_form(nr=0)
br.submit()

br.select_form(nr=0)
br.form['username'] = 'myusername'
br.form['password'] = 'mypassword'
br.submit()

br.select_form(nr=0)
br.submit()

rs = br.open('https://ent.unr-runn.fr/uPortal/f/u1240l1s214/p/esup-mondossierweb.u1240l1n228/max/render.uP?pP_org.apache.myfaces.portlet.MyFacesGenericPortlet.VIEW_ID=%2Fstylesheets%2Fetu%2Fdetailnotes.xhtml')

# Eventually comparing the cookies with those on Live HTTP Header: 
print "Cookies:"
for cookie in cj:
    print cookie

# Displaying page information
print rs.read()
print rs.geturl()
print rs.info();

# And that last line didn't work
rs = br.follow_link(id="formMenu:linknotes1", nr=0)
于 2014-05-29T09:45:11.763 に答える