https および http 認証を備えた pywikipedia ボット
-
12-09-2019 - |
質問
イントラネット上の MediaWiki インストールにボットをログインさせるのに問題があります。http 認証が wiki を保護しているためだと思います。
事実:
- Wiki のルートは次のとおりです。 https://local.example.com/mywiki/
- Web ブラウザで Wiki にアクセスすると、エンタープライズ認証情報を求めるポップアップが表示されます (これは基本的なアクセス認証だと思います)。
これは私のuser-config.pyにあるものです:
mylang = 'en'
family = 'mywiki'
usernames['mywiki']['en'] = u'Bot'
authenticate['local.example.com'] = ('user', 'pass')
これは mywiki_family.py にあるものです:
# -*- coding: utf-8 -*-
import family, config
# The Wikimedia family that is known as mywiki
class Family(family.Family):
def __init__(self):
family.Family.__init__(self)
self.name = 'mywiki'
self.langs = { 'en' : 'local.example.com'}
def scriptpath(self, code):
return '/mywiki'
def version(self, code):
return '1.13.5'
def isPublic(self):
return False
def hostname(self, code):
return 'local.example.com'
def protocol(self, code):
return 'https'
def path(self, code):
return '/mywiki/index.php'
login.py -v -v を実行すると、次の結果が得られます。
urllib2.urlopen(urllib2.Request('https://local.example.com/w/index.php?title=Special:Userlogin&useskin=monobook&action=submit', wpSkipCookieCheck=1&wpPassword=XXXX&wpDomain=&wpRemember=1&wpLoginattempt=Aanmelden%20%26%20Inschrijven&wpName=Bot, {'Content-type': 'application/x-www-form-urlencoded', 'User-agent': 'PythonWikipediaBot/1.0'})):
(Redundant traceback info here)
urllib2.HTTPError: HTTP Error 401: Unauthorized
(なぜ「/mywiki」ではなく「local.example.com/w」になっているのかわかりません。)
example.com/wiki ではなく example.com に対して認証しようとしているのではないかと思い、認証行を次のように変更しました。
authenticate['local.example.com/mywiki'] = ('user', 'pass')
しかし、IIS から HTTP 401.2 エラーが返されます。
Web サーバーが受け入れるように構成されていない WWW-Authenticate ヘッダー フィールドを Web ブラウザが送信しているため、指定した資格情報を使用してこのディレクトリまたはページを表示する権限がありません。
これを機能させる方法について助けていただければ幸いです。
アップデート 家族ファイルを修正すると、次のように表示されます。
サイトMywikiの情報の取得:en( 'http error'、401、 'unauthorized'、)警告:開くことができませんでした 'https://local.example.com/mywiki/index.php?title=Non-existing_page&action=edit&useskin=monobook'。サーバーまたは接続がダウンしている可能性があります。1分後に再試行します...
プランの urllib2.ulropen 呼び出しの HTTP ヘッダーを確認したところ、WWW-Authenticate が使用されています。WWW 認証のネゴシエーション:NTLM。urllib2 と pywikipedia がこれをサポートしていないと思いますか?
アップデート これを機能させるための支援としておいしい報奨金を追加しました。python-ntlm を使用して認証できます。これをpywikipediaに統合するにはどうすればよいですか?
解決
まあ、その事実は login.py
パスの代わりに「\w」にアクセスしようとすると、ファミリー構成に問題があることが示されます。
コードが奇妙にインデントされています:は scriptpath
新しいファミリークラスのメンバーですか?次のように:
class Family(family.Family):
def __init__(self):
family.Family.__init__(self)
self.name = 'mywiki'
self.langs = { 'en' : 'local.example.com'}
def scriptpath(self, code):
return '/mywiki'
def version(self, code):
return '1.13.5'
def isPublic(self):
return False
def hostname(self, code):
return 'local.example.com'
def protocol(self, code):
return 'https'
?
あなたの家族のファイルに何か問題があると思います。確認する良い方法は、Python コンソールで行うことです。
import wikipedia
site = wikipedia.getSite('en', 'mywiki')
print site.login_address()
相対アドレスが間違っていて、「/mywiki」の代わりに「/w」が表示されている限り、ファミリー ファイルがまだ正しく構成されておらず、ボットが機能しないことを意味します :)
アップデート:pywikipediaにntlmを統合するにはどうすればよいですか?
基本的な例を見てみました ここ. 。その行の前のコードを統合します login.py
:
response = urllib2.urlopen(urllib2.Request(self.site.protocol() + '://' + self.site.hostname() + address, data, headers))
次のようなことを書きたいとします。
from ntlm import HTTPNtlmAuthHandler
user = 'DOMAIN\User'
password = "Password"
url = self.site.protocol() + '://' + self.site.hostname()
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, url, user, password)
# create the NTLM authentication handler
auth_NTLM = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(passman)
# create and install the opener
opener = urllib2.build_opener(auth_NTLM)
urllib2.install_opener(opener)
response = urllib2.urlopen(urllib2.Request(self.site.protocol() + '://' + self.site.hostname() + address, data, headers))
利用可能な ntlm セットアップがあれば、これをテストして pywikipedia コードベースに直接統合するでしょう...
何が起こっても、解決策とともに消えないでください。私たちはpywikipediaであなたの解決策に興味があります:)
他のヒント
あなたが抱えている問題は、サーバーが基本認証を期待しているのに、クライアントでそれを処理していないことだと思います。マイケル・フォードがハンドリングについて良い記事を書きました Python での基本認証.
これについて確信できるだけの十分な情報が提供されていないため、問題が解決しない場合は、接続試行のネットワーク ダンプなどの追加情報を提供してください。