Установка авторизации по Active Directory

Цель - чтобы пользователь, который авторизован в Active Directory у себя в винде, мог зайти в web-приложение на netdb без дополнительной авторизации. А если он еще не авторизован - то мы бы смогли его авторизовать. Эту задачу должен решать mod_auth_kerb.

Настройка сервера

Инструкция написана для Fedora 18, но в других Linux дистрибутивах по идее все должно быть так же (за вычетом путей к конфигам апача и некоторых других очевидных деталей).

Считаем что наш сервер называется netdb.local (если это тестовый локальный сервер - добавить его в /etc/hosts).

Чтобы мы могли проверять авторизацию через Active Directory, для сервера нужно завести пользователя (без администраторских привелегий) - назовем его «apache». Проверим что он может авторизоваться (kinit apache).

Далее для него нужно сгенерировать keytab - на сервере с Active Directory делаем (ADapache - это ДОМЕНпользователь):

C:\>ktpass -princ HTTP/netdb.local@AD.CHTD.LAN
 -mapuser apache@AD.CHTD.LAN -crypto rc4-hmac-nt
 -ptype KRB5_NT_SRV_HST -pass SECRET_PASSWORD_GOES_HERE
 -out c:\apache.keytab

Получившийся keytab передаем на сервер с Apache, кладем в /etc/httpd/conf/apache.keytab, проверяем:

kinit -k -t /etc/httpd/conf/apache.keytab HTTP/netdb.local
klist
Ticket cache: DIR::/run/user/1000/krb5cc_a68850848026c34d37838eac51ef99e6/tktdmsNwC
Default principal: HTTP/netdb.local@AD.CHTD.LAN

Valid starting     Expires            Service principal
07/24/13 20:33:17  07/25/13 06:33:16  krbtgt/AD.CHTD.LAN@AD.CHTD.LAN
        renew until 07/31/13 20:33:17

Устанавливаем модуль апача mod_auth_kerb (из пакетов), убеждаемся что он активирован. Конфиг для апача _conf/httpd.ad.conf. Для отладки полезно включить полное логирование - добавить в основной конфиг:

LogLevel debug

Важно чтобы kerberos правильно понял имя сервера, которое нужно использовать при авторизации - в логах он будет писать:

Trying to verify authenticity of KDC using principal HTTP/netdb.local@

Если вместо этого он пишет имя сервера localhost.localdomain - ничего работать не будет, имя сервера должно в точности совпадать. При локальной установке с этим была проблема, решилось тем что в /etc/hosts сначала написал правило для netdb.local, а уже потом для localhost.localdomain.

Важный параметр в конфиге сервера - это:

KrbMethodK5Passwd on

Если он стоит в on, то при первой авторизации нам покажут диалог как при basic auth, и проверят наш логин/пароль в сервер Active Directory. Но для «правильной» работы - когда браузер смотрит авторизованы ли мы и использует «negotiation (см далее пример с curl) он должен стоять off. Как настроить различные браузеры написано тут http://www.roguelynn.com/words/apache-kerberos-for-django/.

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

Еще один вариант проверки авторизации - при помощи curl (http://www.roguelynn.com/words/apache-kerberos-for-django/):

[chtd@localhost netdb_demo]$ kdestroy

[chtd@localhost netdb_demo]$ curl -I --negotiate -u : http://netdb.local
HTTP/1.1 401 Unauthorized
Date: Thu, 25 Jul 2013 14:23:29 GMT
Server: Apache/2.4.4 (Fedora) mod_auth_kerb/5.4
WWW-Authenticate: Negotiate
WWW-Authenticate: Basic realm="
Content-Type: text/html; charset=iso-8859-1

[chtd@localhost netdb_demo]$ kinit testuser
Password for testuser@AD.CHTD.LAN:

[chtd@localhost netdb_demo]$ curl -I --negotiate -u : http://netdb.local
HTTP/1.1 401 Unauthorized
Date: Thu, 25 Jul 2013 14:23:51 GMT
Server: Apache/2.4.4 (Fedora) mod_auth_kerb/5.4
WWW-Authenticate: Negotiate
WWW-Authenticate: Basic realm="
Content-Type: text/html; charset=iso-8859-1

HTTP/1.1 302 FOUND
Date: Thu, 25 Jul 2013 14:23:51 GMT
Server: WSGIServer/0.1 Python/2.7.3
WWW-Authenticate: Negotiate YIGVBgkqhkiG9xIBAgICAG+BhTCBgqADAgEFoQMCAQ+idjB0oAMCAReibQRr+Rm5bVkcymeaJHR2qTVZG8mcuotB9mEDNU8ipzUs84FUVDARA3TMGju6weJi94qER//tRet6CAOkbpwM4x3gRzYG/u/Nd3Xby6aB62HZgawFhyOINFlrMbA3lBTjy9zmvenb8DnFVqimVoQ=
Vary: Accept-Language,Cookie
Content-Type: text/html; charset=utf-8
Location: http://netdb.local/login/?next=/
Content-Language: ru

Авторизованный пользователь будет доступен в переменной request.META:

request.META['REMOTE_USER'] -> 'testuser@AD.CHTD.LAN'

Далее авторизация происходит аналогично https://docs.djangoproject.com/en/1.4/howto/auth-remote-user/

Настройка проекта

Если в netdb_demo.settings.common задана переменная REMOTE_USER_AUTH = True, то подключается возможность авторизации по REMOTE_USER.

Если там же задана переменная REMOTE_USER_AUTOCREATE = True, то если пользователь не найден, создается новый пользователь, если получается найти для него домен. Название домена берется из полного имени пользователя (все что после @). Сам домен ищется среди всех доменов - и берется домен, у котого задан показатель ldap_domain_name (-902, «Название домена LDAP»), равный названию домена пользователя.