<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Добрый день!<div class=""><br class=""></div><div class="">Хочу посоветоваться.</div><div class="">Есть сервер, где зона «для сотрудников» закрыта двумя слоями авторизации:</div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>auth_basic</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>+ проверка на уровне приложения, с куками, сессиями и прочим.</div><div class=""><br class=""></div><div class="">Отказываться от auth_basic не хочется: </div><div class=""><ul class=""><li class="">В коде приложения запросто могут быть ошибки. Забыли, например, завернуть какую-нибудь функцию приложения в декоратор и получили дырку в защите.</li><li class="">Сессионную куку могут угнать. XSS, «мутные» плагины для браузеров и т. д.</li><li class="">Есть «интимная» статика, которую проверять через auth_request не хочется, т.к. замедляет.</li></ul></div><div class="">Проблема в том, что большинство браузеров неудобно работают с basic_auth: Сафари под iPhone спрашивает пароль каждые несколько часов и даже не заморачивается, чтобы его запомнить. FireFox после рестарта показывает модальный диалог со вводом пароля в одном из окон и блокирует все остальные окна с тем же сайтом. Неудобно, короче.</div><div class=""><br class=""></div><div class="">Настроил клиентские сертификаты. Есть сотни мануалов, ничего интересного. Но вот раздача сертификатов сотрудникам и установка их в браузеры – дело муторное. У каждого браузера свои тараканы, сложно объяснить сотруднику по телефону, как поставить сертификат в его браузер и т. д. А если сертификат устареет или придётся его отозвать, совсем беда.</div><div class=""><br class=""></div><div class="">Поэтому решил сделать вот какую логику:</div><div class=""><ul class=""><li class="">Если браузер предъявил сертификат, то <i class="">auth_basic</i> не требуем.</li><li class="">Если не предъявил, то пусть вводит логин+пароль через <i class="">auth_basic</i>.</li><li class="">Проверка доступа на уровне приложения никуда не девается, работаем по старому.</li></ul></div><div class="">Я не нашёл способа, как настроить конфиг nginx, чтобы эту логику реализовать. Конструкции с</div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">if $ssl_client_verify == "SUCCESS" {}</div></blockquote><div class="">несовместимы с auth_basic.</div><div class=""><br class=""></div><div class="">Пока придумал только одно: отпатчил <i class="">ngx_http_auth_basic_module.c</i>, сделал в нём директиву</div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><i class="">auth_basic_skip_if_client_cert</i>    <i class="">on/off</i></div></blockquote>по которой проверка пароля выключается, если предъявлен валидный клиентский сертификат.<div class=""><br class=""></div><div class="">Вопросы:</div><div class=""><ol class=""><li class="">Может быть, кто-то решал аналогичную задачу? Чтоб и два слоя защиты для страховки и удобство в повседневной работе?</li><li class="">Существует ли решение без патча ngx_http_auth_basic_module.c?</li><li class="">Интересен ли кому-нибудь этот патч? Может, на моём велосипеде ещё кто-нибудь хочет покататься? :) </li></ol></div><div class=""><br class=""></div><div class="">С уважением,</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>Владислав</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div></body></html>