Symfony2 двофакторна авторизація за допомогою сертифіката

Мова піде про Symfony2-CertAuthBundle — бандл для популярного фрейморка Symfony2, який дозволяє легко впровадити двофакторну автентифікацію на основі сертифікатів x509 клієнтів.

Іноді стандартної аутентифікації у вигляді форми логіна недостатньо, щоб надійно захистити проект.

Хтось може підглянути, проснифить, будь-яким іншим способом отримати логін пароль, ну або просто зламати сайт і отримати доступ до всіх учетка.

Для тих, хто вважає, що його проекту потрібен більш надійний метод захисту ласкаво просимо під кат.

Установка докладно описана на гітхабі, нижче хочу розповісти про те як це працює і які основні можливості пакету.

Як працює аутентифікація Symfony2 взагалі?
Компонент Security в симфоні спочатку здається дуже складним і запутаным. Але насправді, все дуже просто і логічно.

Security складається з чотирьох основних елементів: FirewallListeners, AuthenticationProviders, UserProviders і AuthenticationManager.

image

FirewallListeners впроваджуються класом Firewall. Вони по ланцюжку обробляють запит на етапі kernel.request. Основне їх завдання — створення неаутентифицированного сертифіката, який буде аутентифікований подальшим AuthenticatedProvider'ом. Так само вони відповідають за серіалізацію і десеріалізацію сертифіката в сесії (ContextListener), за редирект користувача на https (ChannelListener), за ACL (AccessListener).

Для кожного фаєрвола, симфоні створює свій набір инстансов листенеров. Робиться це в SecurityExtension.
Під влади листенера будь-які маніпуляції з сесією і токеном — разлогин користувача, додавання динамічних ролей, зміна токена і т. д. і т. п.

За допомогою AuthenticationManager, листенеры взаємодіють з AuthenticationProvider'ами. Основне завдання провайдерів, за допомогою UserProvider завантажити користувача та повернути аутентифицированый токен — токен хоча б з однією роллю.

AuthenticationManager реалізує нестроге відповідність між листенерами і провайдерами допомогою supports() методу, що дозволяє писати універсальні листенеры і провайдери.

Усі ці компоненти склеюються воєдино в SecurityExtension.

Як працює бандл?
Бандл додає ще один крок аутентифікації у вигляді генерації і скачуванні сертифіката користувача.

Користувачеві пропонується ввести секретне слово. Воно необхідно для шифрування сертифіката перед передачею клієнта і збереженням на сервері.

Так само секретне слово використовується при відновленні сертифіката, якщо користувач втратив, прийшов за інший ноутбук або просто перевстановив систему. Даний функціонал можливо вимкнути і додати свою логіку з ручного відновлення сертифіката (останній дзвінок, смс, остання операція на сайті і т. д.)

Після завантаження та установки сертифіката в браузер, користувач отримує повний доступ. Бандл створює CertifiedUserToken, який успадковується від стандартного UserNamePasswordToken, а так же додає динамічну роль ROLE_CERT_AUTHENTICATED_FULLY, яка використовується у вищезгаданому AccessListener для перевірки доступу.

Основна перевірка клієнтського сертифіката лягає на backend-сервер nginx, apache), які передають в symfony результат перевірки і сам сертифікат. Назви змінних налаштовуються в конфіг. файлі. Бандл лише перевіряє результат цієї перевірки. Перевірка проводиться використовуючи Symfony Expression Language і за замовчуванням має вигляд:


cert["subject"]["CN"] == token.getUserName() && request.server.get("CLIENT_CERT_OK") === "SUCCESS"


У контексті вираження: cert (масив у форматі openssl_x509_parse), об'єкт request і поточний token.

Так як сервер автоматично перевіряє validFrom і validTo сертифіката, неактивні облікові записи з часом не стають потенційною проломом безпеки.

Система зберігання (сервіс zim_cert_auth.certificate_storage) використовує три основних компоненти: Formatter, Filters, Persister.
Formatter відповідає за перетворення x509 ресурсу в формат зберігання. На даний момент реалізовано тільки PKCS12 форматер.
Filter дозволяє застосувати будь-які перетворення перед збереженням або витягом.
Persister відповідає за фізичне збереження сертифікатів. На даний момент реалізовані localfs і orm персистеры. Їх призначення зрозуміло з назви. У планах додати remotessh персистер який дозволить зберігати сертифікати на будь-якому іншому хості використовуючи scp.

Ви можете реалізувати свої сервіси форматеров, персистеров, фільтрів і визначити їх у config.yml

Керування сертифікатами
Бандл додає кілька команд cli для возвожности управління сертифікатами. На даний момент існують дві команди:
zim:cert:dump і zim:cert:remove.

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

Всім дякую.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.