## Please edit system and help pages ONLY in the master wiki!
## For more information, please see MoinMoin:MoinDev/Translation.
##master-page:HelpOnAuthentication
##master-date:2010-02-08T03:41:58Z
#acl -All:write Default
#format wiki
#language ru

<<TableOfContents>>

= Схема работы аутентификации в МойнМойн =

МойнМойн поддерживает различные настраиваемые модули аутентификации для поддержки различных способов аутентификации, как встроенных, так и сторонних.

Параметр конфигурации `auth` используется для задания списка модулей аутентификации, используемых в указанном в списке порядке.

При использовании внешней базы пользователей нет необходимости в заведении всех учётных записей МойнМойн вручную. Для этих целей те модули аутентификации, которые поддерживают создание/обновление учётной записи, поддерживают параметр `autocreate`. Если задать ему значение «`True`», учётная запись будет создана/обновлена когда (новый) пользователь успешно аутентифицируется.

На данный момент поддерживаются следующие модули аутентификации:
||<rowbgcolor="#ffffcc"> '''Конфигурация сервера'''         || '''Способ аутентификации'''                                                                   || '''Название класса модуля аутентификации в МойнМойн''' ||
||<|8 (> Любая                                              || Самим МойнМойн по имени учётной записи и паролю                                               || `MoinMoin.auth.MoinAuth` ||
|| По PHP-сессии                                                                                                                                             || `MoinMoin.auth.php_session.PHPSessionAuth` ||
|| Самим МойнМойн с использованием внешней куки                                                                                                              || см. `contrib/auth_externalcookie/` и ПомощьПоАутентификации/ExternalCookie||
|| По [[http://openid.net/|OpenID]]                                                                                                                          || `MoinMoin.auth.openidrp.OpenIDAuth` ||
|| Верификация OpenID при помощи http://botbouncer.com/                                                                                                      || `MoinMoin.auth.botbouncer.BotBouncer` ||
|| МойнМойн через LDAP                                                                                                                                       || `MoinMoin.auth.ldap_login.LDAPAuth` ||
|| МойнМойн посредством удалённой вики                                                                                                                       || `MoinMoin.auth.interwiki` — находится в экспериментальном состоянии ||
|| По конфигурации МойнМойн, фиксированные имена учётных записей                                                                                             || `MoinMoin.auth.GivenAuth` ||
|| Любой веб-сервер, устанавливающий переменную REMOTE_USER || Например, HTTP Basic, HTTP Digest, SSPI (также известный как NTLM) или аутентификация по LDAP || `MoinMoin.auth.GivenAuth` ||
|| Apache+SSL                                               || Посредством Apache с использованием SSL-сертификата клиента                                   || `MoinMoin.auth.sslclientcert.SSLClientCertAuth` ||

Модули псевдоаутентификации — данные модули не являются модулями аутентификации, так как не занимаются ею, но используют аутентификационную информацию для различных целей.
||<rowbgcolor="#ffffcc"> '''Имя класса''' || '''Описание''' ||
|| `MoinMoin.auth.log.AuthLog`            || Записывает информацию о различных событиях (аутентификация, завершение сессии, запрос) в лог. ||
|| `MoinMoin.auth.smb_mount.SMBMount`     || Монтирует с использованием логина/пароля, указанных во время аутентификации, доступные по SMB каталоги и отключает их при завершении сессии. ||

== Модули в составе дистрибутива ==
=== MoinAuth (модуль по умолчанию) ===

Ниже представлен список модулей аутентификации по умолчанию (как следствие, если он подходит, нет необходимости настраивать его).
{{{#!python
    from MoinMoin.auth import MoinAuth
    auth = [MoinAuth()]
}}}

=== Предоставляемая аутентификация ===
==== Аутентификация, предоставляемая переменной окружения REMOTE_USER ====

Веб-серверы (например, Apache) зачастую поддерживают различные способы аутентификации, встроенные или посредством подключаемых модулей (например, HTTP basic auth). Если сервер настроен на использование аутентификации, то она выполняется до вызова МойнМойн. При посещении ресурса ,требующего аутентификацию, пользователь увидит диалоговое окно обозревателя с запросом имени учётной записи и пароля. После отправки формы аутентификации, может произойти одна из двух вещей:
 * Пара имя учётной записи/пароль некорректна, в этом случае запрос аутентификации будет выполнен повторно (при отмене запроса ,доступ будет запрещён с кодом ошибки HTTP «[[http://en.wikipedia.org/wiki/List_of_HTTP_status_codes|401 not authorized]]» — «авторизация не выполнена»)
 * Пара имя учётной записи/пароль верна, веб-сервер передаёт авторизованное имя МойнМойн (через переменную окружения `REMOTE_USER`)

Модуль аутентификации `GivenAuth` по умолчанию пытается выполнить аутентификацию в МойнМойн, используя имя пользователя, указанное в переменной окружения `REMOTE_USER`.

Для использования аутентификации посредством переменной окружения `REMOTE_USER` необходимо добавить следующие строки в `wikiconfig.py`:
{{{#!python
    from MoinMoin.auth import GivenAuth
    auth = [GivenAuth(autocreate=True)]
}}}

==== Использование других переменных окружения ====

Можно использовать какую-нибудь другую переменную окружения вместо `REMOTE_USER` для аутентификации, указав его в аргументе `env_var` конструктора класса модуля аутентификации:
{{{#!python
    from MoinMoin.auth import GivenAuth
    auth = [GivenAuth(env_var='ЧТО_УГОДНО', autocreate=True)]
}}}

==== Кодировка имени учётной записи ====

Переменная окружения `REMOTE_USER` (или другая, указанная в аргументе `env_var`) содержит строку в некоей кодировке и, как следствие, должна быть декодирована в строку Юникод. Если кодировка не задана, будет сделана попытка декодировать её как строку в UTF-8, потом как строку в Latin-1 (в указанном порядке). Для символов, отличных от набора ASCII, это может привести к некорректным результатам в случае, если веб-сервер использует иную кодировку.

В случае, если поведение по умолчанию приводит к неверным результатам, необходимо явно указать используемую кодировку:
{{{#!python
    auth = [GivenAuth(env_var='WHATEVER', autocreate=True, coding='cp1251')]
}}}

==== Преобразование имени учётной записи ====

В некоторых случаях имя учётной записи, переданное посредством переменной окружения, требует некоего преобразования для использования его на вики.

Модуль аутентификации !GivenAuth имеет ряд флагов для поддержки некоторых стандартных видов преобразований, которые можно при необходимости включить путём задания значения `True` соответствующим аргументам (по умолчанию они выключены и соответствующие аргументы имеют значение `False`):
||<rowbgcolor="#ffffcc"> '''Аргумент'''       || '''Исходное значение'''       || '''Преобразованное значение''' || '''Описание''' ||
|| `strip_maildomain`                         || `joe@example.org`             || `joe`                          || Удаляет почтовый домен из аргумента, оставляя только имя пользователя ||
|| `strip_windomain`                          || `ДОМЕН\имя`                   || `имя`                          || Удаляет домен Windows из аргумента, оставляя только имя пользователя ||
|| `titlecase`                                || `александр привалов`          || `Александр Привалов`           || Делает первый символ каждого слова аргумента заглавным ||
|| `remove_blanks`                            || `Александр Привалов`          || `АлександрПривалов`            || Удалёет пробельные символы из аргумента ||

(!) Преобразования применяются (если они включены) в указанном в таблице выше порядке.

Например, для вики в Windows-домене может использоваться следующая конфигурация:
{{{#!python
    auth = [GivenAuth(autocreate=True, strip_windomain=True, titlecase=True, remove_blanks=True)]
}}}

==== Аутентификация как фиксировано заданным в конфигурации пользователем ====

Также можно жёстко задать в конфигурации фиксированное имя учётной записи:
{{{#!python
    from MoinMoin.auth import GivenAuth
    auth = [GivenAuth(user_name=u'Александр Привалов', autocreate=True)]
}}}

Любой запрос к вики будет являться запросом от данного пользователя автоматически.

=== Аутентификация по SSL-сертификату клиента ===

Для включения аутентификации посредством клиентских сертификатов SSL необходимо добавить в `wikiconfig.py` следующее:
{{{#!python
    from MoinMoin.auth.sslclientcert import SSLClientCertAuth
    auth = [SSLClientCertAuth()]
}}}

Аутентификация по SSL-сертификатам клиента должна использоваться совместно с веб-сервером, который реализует её (например, Apache) и передаёт МойнМойн только ряд переменных окружения.

Модуль аутентификации SSLClientCertAuth имеет ряд параметров, которые могут быть переданы в качестве аргументов конструктору класса (пример приведён далее):  

||<rowbgcolor="#ffffcc"> '''Параметр''' || '''Значение по умолчанию''' || '''Описание''' ||
|| `authorities`                        || `None`                      || Список допустимых authority, или `None` для допуска любых authority. ||
|| `email_key`                          || `True`                      || Указывает, должен ли использоваться содержащийся в сертификате почтовый адрес для поиска учётной записи МойнМойн. ||
|| `name_key`                           || `True`                      || Указывает, должно ли использоваться содержащееся в сертификате имя для поиска учётной записи МойнМойн. ||
|| `use_email`                          || `False`                     || Если значение параметра равно `True`, будет использоваться почтовой адрес, указанный в сертификате, и не будет возможности его сменить. ||
|| `use_name`                           || `False`                     || if set to True, the account name cannot be changed and is forced to the one given in the certificate ||
|| `autocreate`                         || `False`                     || Если значение параметра равно `True`, учётные записи МойнМойн будут создаваться автоматически при необходимости. ||

Например, для допуска только проверенных Apache сертификатов, подписанных определённым authority, можно использовать следующую конструкцию:
{{{#!python
    from MoinMoin.auth.sslclientcert import SSLClientCertAuth
    auth = [SSLClientCertAuth(authorities=['my.authority.tld'])]
}}}
Или аналогичную.

=== PHP-сессия ===

Для использования единой с PHP-приложениями аутентификации необходимо использовать класс PHPSessionAuth из модуля php_session. Он читает файлы PHP-сессий и таким образом обеспечивает интеграцию с существующими системами авторизации в PHP.

Для использования данного модуля конфигурации достаточно добавить следующие строки в конфигурацию:
{{{#!python
    from MoinMoin.auth.php_session import PHPSessionAuth
    auth = [PHPSessionAuth()]
}}}

Конструктор класса PHPSessionAuth имеет следующие аргументы:
{{{#!python
    PHPSessionAuth(apps=['egw'], s_path="/tmp", s_prefix="sess_")
}}}
 * `apps` — список разрешённых приложений.
 * `s_path` — путь к файлам PHP-сессий.
 * `s_prefix` — префикс имен файлов PHP-сессий.

На данный момент из PHP-приложений поддерживается только eGroupware 1.2. Тем не менее, достаточно просто добавить поддержку других приложений путём добавления нескольких строк кода, извлекающих необходимую информацию из PHP-сессии. Если таковое будет реализовано, просьба создать [[MoinMoin:FeatureRequests|запрос на добавление функциональности]] с соответствующим патчем.

=== Авторизация по OpenID (с использованием BotBouncer) ===

Модуль аутентификации по OpenID позволяет пользователям аутентифицироваться используя их OpenID и ассоциировать данный OpenID с новой или существующей учётной записью МойнМойн. Для того, чтобы пользователи могли аутентифицироваться с использованием OpenID, необходимо добавить модуль в список параметра `auth`:
{{{#!python
    from MoinMoin.auth.openidrp import OpenIDAuth
    auth = [OpenIDAuth()]
}}}
Для верификации OpenID сервисом http://botbouncer.com/ Необходимо добавить в конфигурацию следующее:
{{{#!python
    from MoinMoin.auth.botbouncer import BotBouncer
    auth = [BotBouncer("ключ-botbouncer-API")]
}}}

Аутентификации по OpenID для работы требуется включённая поддержка анонимных сессий, для чего достаточно установить первый элемент значения параметра `cookie_lifetime` конфигурации в значение, большее нуля (например, `cookie_lifetime = (2,12)`). См. КакНастраивать и ПомощьПоСеансам для дополнительной информации по параметру. Для OpenID достаточно небольшого времени жизни сессии.

==== Дополнительная настройка OpenID RP ====

Модуль OpenID RP может быть также настроен для двух следующих вариантов использования:
 1. Использование определённого OpenID-провайдера. Существует два способа решить данную задачу:
  * Указать соответствующий аргумент в конструкторе класс модуля аутентификации: {{{#!python
auth = OpenIDAuth(forced_service='http://myopenid.com/')
}}}
  * Создать экземпляр класса `OpenIDServiceEndpoint` и передавать его в качестве значения аргумента `forced_service` конструктора: {{{#!python
fs = OpenIDServiceEndpoint()
fs.type_uris = OPENID_2_0_TYPE
fs.server_url = 'http://localhost:8000/openidserver'
fs.claimed_id = 'http://specs.openid.net/auth/2.0/identifier_select'

auth = OpenIDAuth(forced_service=fs)
}}}
 Во втором случае нет необходимости выполнять discovery.
 1. Можно задать функции, вызываемые на различных этапах процесса аутентификации по OpenID для, например, реализации обмена атрибутами. На данный момент эта возможность недокументирована, для дополнительной информации см. файл `MoinMoin/auth/openidrp.py`.

=== Аутентификация с использованием LDAP ===

Модуль аутентификации LDAP МойнМойн позволяет использовать единую аутентификацию (single-sign-on, SSO) — в предположении, что уже меется каталог LDAP с пользователями, паролями и почтовыми адресами. На системах с Linux для этих целей обычно используется сервер OpenLDAP, на серверах с Windows (обычно, контроллерах домена) данный сервис называется «Active Directory» (AD).

Процесс аутентификации выглядит следующим образом:
 * Пользователь вводит имя учётной записи и пароль в форме аутентификации МойнМойн и кликает по кнопке «<<GetText(Login)>>».
 * Класс `ldap_login.LDAPAuth` проверяет валидность пары имя учётной записи — пароль в LDAP.
  * Если реквизиты аутентификации валидны в LDAP, то модуль аутентификации создаёт или обновляет учётную запись МойнМойн значениями из LDAP  (имя, ник, почтовый адрес) и создаёт объект с контекстом пользователя в адресном пространстве процесса сервера МойнМойн, после чего передаёт управление следующему модулю аутентификации.
  * Если реквизита аутентификации невалидны в LDAP, то процесс аутентификации завершается неудачно.
 * Если аутентификация выполнена успешно, МойнМойн создаёт объект сессии для данного пользователя.

==== Начальное и последующее конфигурирование аутентификации с использованием LDAP ====

Предварительно необходимо установить модуль Python [[http://www.python-ldap.org|python-ldap]] со всеми его зависимостями, см. его документацию.

Также необходим сервер LDAP или AD.

См. Файл `wiki/config/more_samples/ldap_wikiconfig_snippet.py` в архиве дистрибутива МойнМойн для примера конфигурации, которую можно использовать в конфигурации вики.

(!) Также рекомендуется прочитать файл `README`, находящийся в том же каталоге.

==== Проблемы при использовании LDAP ====

Поддержка проекта МойнМойн не имеет никакой информации о используемой в конкретных случаях конфигурации LDAP-сервера, поэтому перед  задаванием вопросов рекомендуется придерживаться следующих шагов:
 * Включить вывод отладочной печати в модуле `MoinMoin.ldap_login` и просмотреть отладочный вывод.
 * Проверить конфигурацию и валидность имени учётной записи а пароля, воспользовавшись утилитой для запросов к LDAP-сервера.
  * /!\ Если взаимодействие с сервером при помощи данной утилиты не увенчалось успезом, не стоит пытаться с использованием МойнМойн.
 * Посоветуйтесь с администратором сервера AD/LDAP относительно помощи и корректной конфигурации.
 * Возможно, чтоит посмотреть на `MoinMoin/auth/ldap_login.py` при наличии должных навыков в отладк и поиске проблем.

/!\ Обращайтесь в поддержку МойнМойн только в случае, если удалось успешно воспользоваться `ldapsearch` (или аналогичной утилитой) и после тщательной проверки конфигурации вики.

=== Аутентификация с использованием XMLRPC ===

{{{#!python
# -*- codung: utf-8 -*-
import xmlrpclib

name = "ТестовыйПользователь"
password = "пароль"
wikiurl = "http://localhost:8080/"

homewiki = xmlrpclib.ServerProxy(wikiurl + "?action=xmlrpc2", allow_none=True)
auth_token = homewiki.getAuthToken(name, password)

mc = xmlrpclib.MultiCall(homewiki)
mc.applyAuthToken(auth_token)
# Здесь можно добавить дополнительные вызовы методов XML RPC в MultiCall()
# Они будут выполнены с аутентификационной информацией пользователя.
result = mc()
}}}

== Совместное использование нескольких модулей аутентификации ==

Для объединения, например, аутентификации по SSL-сертификату клиента и по имени учётной записи и паролю, `wikiconfig.py` должен содержать следующее:
{{{#!python
    from MoinMoin.auth import MoinAuth
    from MoinMoin.auth.sslclientcert import SSLClientCertAuth
    auth = [SSLClientCertAuth(), MoinAuth()]
}}}

В этом случае, сертификаты, предоставляемые пользователем, будут использоваться для его аутентификации, но в случае их отсутствия сохраняется возможность аутентификации по имени учётной записи и паролю.

== Написание собственного модуля аутентификации ==

См. закомментированную часть конфигурационного файла `contrib/auth_externalcookie/` и файлы `MoinMoin/auth/*.py`, поставляемые в составе дистрибутива, для примеров реализации модулей аутентификации. Кроме того, документация в `MoinMoin/auth/__init__.py` содержит описание того, что может быть сделано и как этого можно достигнуть.

Модули аутентификации имеют следующие возможности:
 * Использовать стандартную форму аутентификации как пользовательский интерфейс для ввода учётной записи и пароля
 * Использовать стандартное действие завершения сеанса для завершения сеанса.
 * Запрещать завершение сессии (например, при аутентификации по SSL-сертификату, проверяемому при каждом запросе).
 * Просматривать существующие учётные записи для поиска подходящей (для подбора может использоваться не только имя учётной записи, но также и почтовый адрес и ник)
 * Создавать объекты пользователей и позволять им хранить данные, указанные модулем аутентификации.
 * Обновлять учётную записи внешними данными
 * Автоматически создавать учётные записи
