pywikипедийный бот с аутентификацией по https и http
-
12-09-2019 - |
Вопрос
У меня возникли проблемы с подключением моего бота к установке MediaWiki в интрасети.Я полагаю, что это связано с http-аутентификацией, защищающей wiki.
Факты:
- Корень wiki - это: https://local.example.com/mywiki/
- При посещении 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
(Я не уверен, почему в нем 'local.example.com/w' вместо '/mywiki'.)
Я подумал, что это может быть попытка аутентификации с помощью example.com вместо example.com/wiki, поэтому я изменил строку аутентификации на:
authenticate['local.example.com/mywiki'] = ('user', 'pass')
Но затем я получаю сообщение об ошибке HTTP 401.2 от IIS:
У вас нет разрешения на просмотр этого каталога или страницы с использованием предоставленных вами учетных данных, поскольку ваш веб-браузер отправляет поле заголовка WWW-Authenticate, которое веб-сервер не настроен принимать.
Буду признателен за любую помощь о том, как заставить это работать.
Обновить После исправления моего семейного файла, теперь там написано:
Получение информации для сайта mywiki:ru ("ошибка http", 401, "Неавторизованный",) ПРЕДУПРЕЖДЕНИЕ:Не удалось открыть 'https://local.example.com/mywiki/index.php?title=Non-existing_page&action=edit&useskin=monobook'.Возможно, сервер или ваше соединение отключены.Повторите попытку через 1 минуту...
Я просмотрел HTTP-заголовки в вызове plan urllib2.ulropen, и он использует WWW-Authenticate:Согласование WWW-Аутентификации:NTLM.Я предполагаю, что urllib2 и, следовательно, pywikипедия не поддерживают это?
Обновить Добавлена вкусная награда за помощь в том, чтобы заставить это работать.Я могу пройти аутентификацию с помощью python-ntlm.Как мне интегрировать это в pywikedia?
Решение
Ну, тот факт, что 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()
пока указан неверный относительный адрес, показывающий '/ w' вместо '/ mywiki', это означает, что семейный файл по-прежнему настроен неправильно, и бот не будет работать :)
Обновить:как интегрировать ntlm в pywikипедию?
Я только что взглянул на базовый пример здесь.Я бы интегрировал код перед этой строкой в 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))
Я бы протестировал это и интегрировал непосредственно в кодовую базу pywikипедии, если бы только у меня была доступная настройка ntlm...
Что бы ни случилось, пожалуйста, не исчезайте вместе с вашим решением:мы в pywikипедии заинтересованы в вашем решении :)
Другие советы
Я предполагаю, что проблема, с которой вы столкнулись, заключается в том, что сервер ожидает базовой аутентификации, а вы не обрабатываете это в своем клиенте.Майкл Фурд написал хорошую статью об обращении с базовая аутентификация на Python.
Вы не предоставили достаточно информации, чтобы я мог быть уверен в этом, поэтому, если это не сработает, пожалуйста, предоставьте некоторую дополнительную информацию, например сетевой дамп вашей попытки подключения.