18 янв. 2012 г.

Совмещенная аутентификация в grails-приложениях

В типичном Grails-приложении используется в основном аутентификация с помощью форм. Но в некоторых случаях может потребоваться несколько видов аутентификации в приложении, например, если веб-приложение предоставляет REST-сервисы. Если разрабатываемый в составе Grails-приложения REST-сервис не публичный, необходимо обеспечить механизмы авторизации. Одно из самых популярных решений: защитить сервис с помощью механизма Basic Authentication. При использовании механизма Basic Authentication имя пользователя и пароль, кодированные в Base64, размещаются в HTTP-заголовке "Authorization". Это не самый безопасный механизм аутентификаций, но применяется часто из-за простоты реализации и использования.

Будем рассматривать работу с Grails-плагином Acegi Security, который базируется на коде свободно распространяемого фреймворка Spring Security.

Фреймворк Spring Security поддерживает большое количество протоколов авторизации и предоставляет гибкие механизмы для их настройки. Система безопасности Acegi состоит из компонентов четырех основных типов: фильтров, менеджеров, провайдеров и обработчиков.

Фильтры - наиболее высокоуровневые компоненты, обеспечивающие весь цикл работы системы безопасности. В зависимости от требований к безопасности приложения, можно сочетать и применять различные типы фильтров. Сочетание фильтров безопасности в определенном порядке образует цепочку фильтров.

5 важнейших типов фильтров Spring Security

Существует 5 важнейших типов фильтров:


  • Фильтр для интеграции сеанса (Session Integration Filter, SIF-фильтр). Создается объект контекста безопасности

  • Фильтр для выполнения аутентификации (Authentication Processing Filter, APF-фильтр);

  • Фильтр для выхода из системы (Logout Processing Filter, LPF-фильтр);

  • Фильтр для обработки исключительных ситуаций (Exception Translation Filter, ETF-фильтр) . Обрабатывает случаи, когда авторизация не удалась. Типичная реализация ETF - указать дальнейшие действия системы в случае если аутентификация не удалась или у пользователя недостаточно прав.

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

Настройка конфигурации Acegi Security

После объяснения основных понятий системы Spring Security, вернемся к основной теме статьи. В плагине Acegi Security существует возможность настройки цепочек фильтров для каждого заданного URL. Для этого необходимо использовать атрибут filterInvocationDefinitionSourceMap.

Модифицируем файл с настройками компонентов Spring: resources.groovy, который располагается в директории \grails-app\conf\spring. В начале укажем правильную точку входа для того чтобы сервер возвращал код "401 Unauthorized", если авторизация прошла неудачно:

beans = {
authenticationEntryPoint (org.springframework.security.ui.basicauth.BasicProcessingFilterEntryPoint) {
realmName = 'Grails Realm'
}
}

Если не выполнить данную настройку, оставив значение autenticationEntryPoint по умолчанию, при отсутствии в HTTP-запросе заголовка "Authorization" сервер будет перенаправлять клиента с кодом "302 Found" на страницу авторизации.

Теперь настроим цепочики фильтров для двух случаев. Все ресурсы сайта, за исключением REST-сервиса, будут использовать аутентификацию формами, а REST-сервис - аутентификацию методом HTTP Basic. Для аутентификации формами используем стандартную цепочку фильтров, определенную в системе Acegi Security. Следовательно, необходимо настроить только цепочку фильтров для аутентицикации методом HTTP Basic.

Предположим, что ваш REST-сервис располагается по относительному пути /restservice/. Добавим следующий код в \grails-app\conf\SecurtyConfig.groovy.

filterInvocationDefinitionSourceMap = [
'/restservice/**': 'httpSessionContextIntegrationFilter, logoutFilter, authenticationProcessingFilter, basicProcessingFilter, securityContextHolderAwareRequestFilter, rememberMeProcessingFilter, anonymousProcessingFilter, exceptionTranslationFilter, filterInvocationInterceptor',
'/**': 'JOINED_FILTERS'
] 

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

В итоге мы получили конфигурацию системы безопасности, при которой все запросы по пути /restservice будут требовать аутентификацию методом Basic Authentication, а остальные ресурсы web-приложения - аутентификацию формами.


Комментариев нет:

Отправить комментарий