Обеспечение безопасности Java-приложений с помощью Acegi: Часть 1. Обзор архитектуры и фильтров безопасности

Обеспечение безопасности на основе URL-адресов с использованием инфраструктуры безопасности Acegi

Эта серия из трех статей знакомит с системой безопасности Acegi - отличной инфраструктурой с открытым исходным кодом для корпоративных Java™-приложений. В первой части Билал Сиддикви знакомит с архитектурой и компонентами Acegi и показывает, как пользоваться ими для организации безопасности простого корпоративного Java™-приложения.

Билал Сиддикви, внештатный консультант, WaxSys

Билал Сиддикви (Bilal Siddiqui) является инженером-электронщиком, консультантом по XML и соучредителем WaxSys, компании, чья деятельность направлена на упрощение электронного бизнеса. После окончания в 1995 г. Инженерно-технологического Университета, г. Лахор, и получения степени по электронной технике, он начал разрабатывать программные продукты для промышленных систем управления. В дальнейшем он занимался XML и использовал свой опыт в программировании C++ для разработки Web- и Wap-базируемых инструментов для XML-технологий, серверных парсинговых программных продуктов и служебных приложений. Билал – проповедник передовых технологий и часто публикуется в этой области.



14.03.2008

Система безопасности Acegi - это мощная и при этом простая в использовании альтернатива бесконечному написанию кода для обеспечения безопасности корпоративных Java-приложений. Хотя инфраструктура Acegi была изначально предназначена для приложений, написанных с помощью Spring, ее можно использовать и для Java-приложений любого типа. Эта серия статей знакомит с Acegi "с нуля", показывая, как использовать ее для обеспечения безопасности простых и сложных корпоративных приложений.

Эта серия статей начинается с обзора общих проблем безопасности корпоративных приложений и объясняет, как Acegi может помочь решить их. В данной статье будет рассмотрена архитектурная модель Acegi и фильтры безопасности, в которых содержится большая часть функциональности, используемой для защиты приложений. Мы разберем, как фильтры работают по отдельности и как их можно комбинировать, а также рассмотрим, как функционирует вся цепочка фильтрации при реализации безопасности корпоративных приложений. В завершение будет представлен пример приложения, иллюстрирующий реализацию на базе Acegi основанной на URL системы безопасности. В следующих статьях будут рассмотрены более сложные аспекты использования Acegi, включая проектирование и поддержку политик управления доступом, а также настройку Acegi для их использования.

Необходимо скачать Acegi чтобы скомпилировать код и запустить примеры приложений из статей данной серии. Дополнительно на компьютере потребуется запустить Tomcat сервер.

Безопасность корпоративных приложений

ECM-приложения (enterprise content management - корпоративные системы для управления контентом) управляют созданием и обработкой корпоративных данных, хранящихся в хранилищах данных различных типов, таких как файловые системы, реляционные СУБД и службы каталогов. Поэтому для ECM-приложений требуется контролировать доступ к этим источникам данных. Например, ECM-приложение может контролировать, кто имеет право считывать, редактировать или удалять данные, относящиеся к проектированию, маркетингу, производству и контролю качества промышленного предприятия.

В сценарии обеспечения безопасности ЕСМ-приложения обычно нужно реализовать управление доступом, применяя правила безопасности к указателям (или сетевым адресам) корпоративных ресурсов. Эта простая модель безопасности называется безопасностью на основе URL (Universal Resource Locator). Как будет показано далее в этой и последующих статьях, Acegi предоставляет всю необходимую функциональность для реализации безопасности на основе URL.

Однако для большинства корпоративных приложений безопасности на основе URL недостаточно. Например, рассмотрим PDF-документ, содержащий данные о конкретном продукте, выпускаемом компанией. Часть этого документа, содержащая данные о проектировании, должна редактироваться и обновляться отделом проектирования компании. Другая часть документа, содержащая данные о производстве, будет использоваться руководителями производства. Для подобного сценария необходимо реализовать более детальную модель безопасности, применяющую различные права доступа к различным фрагментам документа.

Эта статья знакомит с функциональностью Acegi для обеспечения безопасности на базе URL. В следующей статье будет приведен пример организации системы безопасности с помощью Acegi на основе методов, которая обеспечивает более детальное управление доступом к корпоративным данным.


Система безопасности Acegi

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

  1. Запросить у пользователя имя и пароль при обращении к защищенному ресурсу.
  2. Аутентифицировать пользователя при помощи проверки параметра безопасности, такого как пароль.
  3. Проверить, имеет ли аутентифицированный пользователь права на доступ к защищенному ресурсу.
  4. Перенаправить успешно аутентифицированного и авторизованного пользователя на запрошенный защищенный ресурс.
  5. Показать пользователю страницу "отказано в доступе" если у него нет привилегий для доступа к защищенному ресурсу.
  6. Запомнить успешно аутентифицированного пользователя на сервере и установить cookie безопасности на клиенте пользователя (Web-браузере). Следующая аутентификация может быть выполнена при помощи cookie, без того, заставлять пользователя снова вводить имя и пароль.
  7. Хранить аутентификационную информацию в объектах сеанса на стороне сервера, чтобы обеспечить безопасное обслуживание последующих запросов к ресурсам.
  8. Создать и поддерживать в актуальном состоянии кэш информации, относящейся к безопасности, в виде объектов на стороне сервера для оптимизации производительности.
  9. При выходе пользователя из системы уничтожить объекты на стороне сервера, использовавшиеся для создания защищенного сеанса пользователя.
  10. Взаимодействовать с различными внутренними системами хранения данных, такими как службы каталогов или реляционные СУБД, в которых хранятся параметры безопасности пользователей и политики доступа к ECM-ресурсам.

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


Архитектура и компоненты

Чем лучше вы понимаете Acegi, тем проще вам будет использовать ее на практике. В этом разделе будут представлены компоненты Acegi, а затем будет показано, как эта инфраструктура использует инверсию управления (IoC) и конфигурационные XML-файлы для компоновки компонентов и выражения зависимостей между ними.

Великолепная четверка

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

Фильтры (filters)
Эти наиболее высокоуровневые компоненты обеспечивают базовые службы безопасности: выполнение аутентификации, поддержку пользовательского сеанса и выход из системы. Более подробно фильтры обсуждаются далее в этой статье.
Менеджеры (managers)
Фильтры - это только высокоуровневые абстракции для функциональности системы безопасности. Для фактической реализации аутентификации и выхода из системы используются менеджеры и провайдеры. Менеджеры управляют низкоуровневыми службами, предоставляемыми различными провайдерами.
Провайдеры (providers)
Имеется множество провайдеров для взаимодействия с различными типами систем хранения данных: службами каталогов, реляционными базами данных и простыми объектами в памяти. Благодаря этому можно хранить базу пользователей и политики управления доступом в любом хранилище указанных типов, а менеджеры Acegi выберут подходящих провайдеров во время исполнения.
Обработчики (handlers)
Задачи иногда разбиваются на несколько этапов, и каждый этап выполняется определенным обработчиком. Например, фильтр Acegi для выхода из системы использует два обработчика для отключения HTTP-клиента. Один обработчик уничтожает HTTP-сеанс пользователя, а другой уничтожает cookie-файлы этого пользователя. Наличие множества обработчиков обеспечивает гибкость настройки Acegi для работы в соответствии с требованиями приложения. Вы можете выбирать обработчики по своему желанию для выполнения действий, необходимых, чтобы обеспечить безопасность конкретного приложения.

Инверсия управления (Inversion of Control)

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

Для управления зависимостями между Java компонентами обычно используется реализация IOC. Шаблон IOC обеспечивает две ключевые возможности:

  1. синтаксис, позволяющий выразить, какие компоненты требуются приложению, и как они зависят друг от друга.
  2. 2. проверку того, что требуемые компоненты доступны во время исполнения.

Конфигурационный XML-файл

В инфраструктуре Acegi используется популярная open source-реализация IOC, поставляемая с инфраструктурой Spring (см. раздел Ресурсы) для управления компонентами. В Spring для выражения зависимостей между компонентами используется конфигурационный XML-файл, как показано в листинге 1:

Листинг 1. Структура конфигурационного файла Spring
<beans>
    <bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
        <property name="filterInvocationDefinitionSource">
            <value> value here </value>
        </property>
    </bean>

    <bean id="authenticationProcessingFilter"
        class="org.acegisecurity.ui.webapp.AuthenticationProcessingFitler">
        <property name="authenticationManager" ref="authManager"/>
        <!-- Other properties -->
    </bean>

    <bean id="authManager"
        class="org.acegisecurity.providers.ProviderManager">
        <property name="providers">
            <!--  List of providers here -->
        </property>
    </bean>
    <!-- Other bean tags -->
</beans>

Как видно, конфигурационный XML-файл Spring, используемый Acegi, содержит единственный тег <beans>, содержащий некотороек количество других тегов <bean>. Все компоненты Acegi: фильтры, менеджеры, провайдеры и т.д. на самом деле представляют собой JavaBeans-объекты (bean-компоненты). Каждый тег <bean> в конфигурационном XML-файле представляет компонент Acegi.

Подробный анализ конфигурационного XML-файла

Сначала отметим, что у каждого тега <bean> есть атрибут class, который определяет класс, используемый компонентом. У тега <bean> также есть атрибут id, который используется для уникальной идентификации экземпляра (Java объекта), используемого в качестве компонента Acegi.

Например, первый тег <bean> в листинге 1 определяет компонент, названный filterChainProxy, который является экземпляром класса org.acegisecurity.util.FilterChainProxy.

Зависимости bean-компонентов выражаются с помощью вложенных тегов в теге <bean>. Рассмотрим, к примеру, вложенный тег <property> первого тега <bean>. Вложенный тег <property> определяет значения или другие bean-компоненты, от которых зависит тег <bean>.

В листинге 1вложенный тег <property> первого тега <bean> имеет атрибут name и вложенный тег <value>, который соответственно определяет название и значение свойства, от которого зависит bean-компонент.

Точно так же второй и третий теги <bean> в листинге 1 определяют, что bean-компонент фильтр зависит от bean-компонента менеджера. Второй тег <bean> предоставляет собой фильтр, а третий тег <bean> представляет собой менеджер.

Тег <bean> для фильтра содержит вложенный тег <property> , у которого есть два атрибута name и ref. Атрибут name определяет свойство bean-компонента-фильтра, а атрибут ref ссылается на экземпляр bean-компонента-менеджера, точнее, на его название.

В следующем разделе будет показано, как настроить фильтры Acegi в конфигурационном XML-файле. Далее в статье эти фильтры будут использоваться для приложения-примера Acegi.


Фильтры безопасности

Как упоминалось выше, для предоставления служб аутентификации и авторизации корпоративным приложениям Acegi использует фильтры безопасности. Можно применять и сочетать различные типы фильтров согласно требованиям приложения. Этот раздел знакомит с пятью важнейшими фильтрами безопасности Acegi.

Фильтр для интеграции сеанса

Фильтр для интеграции сеанса (Session Integration Filter - SIF) в Acegi обычно является первым фильтром, который настраивается в первую очередь. SIF-фильтр создает объект контекста безопасности, в котором будет храниться информация, относящаяся к безопасности. Другие фильтры Acegi сохраняют информацию о безопасности в этот контекст, а также используют информацию, доступную в контексте безопасности.

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

Когда все фильтры завершат обработку, SIF-фильтр проверяет контекст безопасности на предмет обновлений. Если обнаруживаются изменения, сделанные каким-либо фильтром, то SIF-фильтр сохраняет их в объект сеанса на стороне сервера. Если же изменений в контексте не обнаружено, то никакие действия не выполняются.

Настройка SIF-фильтра выполняется в конфигурационном XML-файле, как показано в листинге 2:

Листинг 2. Настройка SIF-фильтра
<bean id="httpSessionContextIntegrationFilter"        
     class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"/>

Фильтр для выполнения аутентификации

Фильтр для выполнения аутентификации (Authentication Processing Filter - APF) в Acegi используется для аутентификации. APF-фильтр выдает пользователю форму аутентификации (или входа в систему) для ввода имени пользователя и пароля, а затем запускает процесс аутентификации.

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

При настройке APF-фильтра необходимо указать следующие параметры:

  • Менеджер аутентификаци (Authentication manager), определяющий, какой менеджер аутентификации будет использоваться для управления провайдерами аутентификации.
  • URL-адрес фильтра (Filter processes URL) - этот адрес ведет к ресурсу, который будет вызван, когда клиент нажмет кнопку Sign In на форме для входа в систему. При получении запроса к этому URL-адресу Acegi вызовет APF-фильтр.
  • URL к ресурсу по умолчанию (Default target URL) - этот адрес ведет к странице, которая будет показана пользователю в случае успешного прохождения аутентификации и авторизации.
  • URL в случае неудачной аутентификации (Authentication failure URL) - этот адрес ведет на страницу, показываемую пользователю в случае неудачной аутентификации.

APF-фильтр извлекает имя пользователя, пароль и другую информацию из объекта запроса пользователя. Эта информация передается менеджеру аутентификации, который вызывает соответствующего провайдера, чтобы считать подробную информацию о пользователе (имя пользователя, пароль, адрес электронной почты и права доступа или привилегии) из базы данных пользователей, выполнить аутентификацию и сохранить информацию в объекте Authentication.

В конце APF-фильтр сохраняет объект Authentication в контекст безопасности, ранее созданный SIF-фильтром. Этот объект Authentication, хранящийся в контексте безопасности, потом будет использоваться для принятия решений об авторизации.

Пример настройки APF-фильтра приведен в листинге 3:

Листинг 3. Настройка APF
<bean id="authenticationProcessingFilter"
    class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
    <property name="authenticationManager"
        ref="authenticationManager" />
    <property name="filterProcessesUrl"
        value="/j_acegi_security_check" />
    <property name="defaultTargetUrl"
        value="/protected/protected1.jsp" />
    <property name="authenticationFailureUrl"
        value="/login.jsp?login_error=1" />
</bean>

YИз этого кода можно заметить, что фильтр APF зависит от четырех параметров, упоминавшихся выше. Каждый параметр настраивается с помощью тега <property> как в листинге 3.

Фильтр для выхода из системы

Фильтр для выхода из системы (Logout Processing Filer - LPF) используется в Acegi для управления выходом из системы. LPF-фильтр включается в работу, когда от клиента приходит запрос на выход из системы. Этот запрос определяется по URL-адресу, вызванному клиентом.

LPF-фильтр настраивается, как показано в листинге 4:

Листинг 4. Настройка LPF-фильтра
<bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
    <constructor-arg value="/logoutSuccess.jsp"/>
    <constructor-arg>
        <list>
            <bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
        </list>
    </constructor-arg>
</bean>

Как видно, конструктор LPF-фильтра принимает два параметра: URL-адрес, показываемый в случае успешного выхода из системы, и список обработчиков. На указанный URL-адрес клиент перенаправляется после завершения процесса выхода из системы. Обработчики выполняют процесс выхода из системы, в данном примере настроен только один обработчик - так как для начала достаточно просто уничтожить HTTP-сеанс. Другие типы обработчиков будут рассмотрены в следующей статье.

Фильтр для обработки исключительных ситуаций

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

Например, если не аутентифицированный пользователь попытается получить доступ к защищенному ресурсу, то фильтр ETF-фильтр предложит пользователю аутентифицироваться, отправив его на страницу входа в систему. Аналогично в случае неудачной аутентификации ETF-фильтр можно настроить на отображение страницы "отказано в доступе".

Настройка ETF-фильтра выполняется, как показано в листинге 5:

Листинг 5. Настройка ETF-фильтра
<bean id="exceptionTranslationFilter"
    class="org.acegisecurity.ui.ExceptionTranslationFilter">
    <property name="authenticationEntryPoint">
        <bean 
            class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
            <property name="loginFormUrl" value="/login.jsp" />
        </bean>
    </property>
    <property name="accessDeniedHandler">
        <bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl">
            <property name="errorPage" value="/accessDenied.jsp" />
        </bean>
    </property>
</bean>

Как показано в листинге 5, ETF-фильтр принимает два параметра, называемые authenticationEntryPoint и accessDeniedHandler. Параметр authenticationEntryPoint определяет страницу для входа в систему, а параметр accessDeniedHandler определяет страницу типа "отказано в доступе".

Перехватывающие фильтры

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

В следующей статье будет показано, как проектировать политики управления доступом, как устанавливать их в службу каталогов и как настроить Acegi считывать их оттуда. Сейчас же мы попробуем настроить Acegi для использования самой простой политики доступа. Далее в статье эта политика управления доступом будет использоваться для сборки приложения-примера.

Настройку простой политики управления доступом можно разделить на два этапа:

  1. Написать политику управления доступом..
  2. Настроить перехватывающий фильтр Acegi согласно политике.

Этап 1. Написание простой политики управления доступом

В листинге 6показано, как определить пользователя и роль для него:

Листинг 6. Определение простой политики управления доступом для пользователя
    alice=123,ROLE_HEAD_OF_ENGINEERING

В политике управления доступом, показанной в листинге 6, определяется пользователь alice с паролем 123 и ролью ROLE_HEAD_OF_ENGINEERING. В следующем разделе будет показано, как определить любое число пользователей и их ролей и затем настроить перехватывающий фильтр Acegi на использование этого файла.

Шаг 2. Настройка перехватывающего фильтра Acegi

Для принятия решений по авторизации перехватывающие фильтры используют три компонента, которые настраиваются в листинге 7:

Листинг 7. Настройка перехватывающего фильтра
<bean id="filterInvocationInterceptor"
    class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
    <property name="authenticationManager" ref="authenticationManager" />
    <property name="accessDecisionManager" ref="accessDecisionManager" />
    <property name="objectDefinitionSource">
        <value>
            CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
            PATTERN_TYPE_APACHE_ANT
            /protected/**=ROLE_HEAD_OF_ENGINEERING
            /**=IS_AUTHENTICATED_ANONYMOUSLY
        </value>
    </property>
    <!--  остальные параметры перехватывающего фильтра -->
</bean>

Как видно из листинга 7, необходимо настроить три компонента: authenticationManager, accessDecisionManager, objectDefinitionSource:

  • Компонент authenticationManager - это тот же самый менеджер аутентификации, который обсуждался ранее в разделе Фильтр для выполнения аутентификации. Перехватывающий фильтр может использовать компонент authenticationManager для повторной аутентификации пользователя во время процесса авторизации.
  • Компонент accessDecisionManager управляет процессом авторизации, который будет обсуждаться в следующей статье этой серии.
  • Компонент objectDefinitionSource содержит определения политики безопасности, соответствующей выполняемой авторизации. Например, свойство objectDefinitionSource в листинге 7 содержит в своих значениях два URL-адреса (/protected/* и /*). Эти значения определяют роли для этих URL-адресов. Роль для URL-адреса /protected/* URL - ROLE_HEAD_OF_ENGINEERING. Можно определить любые необходимые роли, требующиеся для приложения.

    Напомним, что в листинге 6 объявлена роль ROLE_HEAD_OF_ENGINEERING для пользователя с именем alice. Это значит, что alice будет иметь доступ к URL-адресу /protected/*.

Как работают фильтры

Как было объяснено ранее, компоненты Acegi обеспечивают безопасность приложения, работая совместно. Далее в этой серии статей будет показано, как настроить Acegi для применения фильтров безопасности в определенном порядке, создав цепочку фильтров. Для этой цели Acegi поддерживает объект-цепочку фильтрации, который является оболочкой для всех фильтров, настроенных для обеспечения безопасности приложения. На рисунке 1 показан жизненный цикл цепочки фильтрации Acegi, начинающийся с отправки клиентом HTTP-запроса в приложение. Рисунок 1 показывает, как контейнер обслуживает запрос от Web-браузера клиента.

Рисунок 1. Контейнер, поддерживающий цепочку фильтрации Acegi для безопасной обработки запроса от Web-браузера клиента
Рисунок 1. Контейнер, поддерживающий цепочку фильтрации Acegi

Жизненный цикл цепочки фильтрации состоит из следующих шагов:

  1. Клиент отправляет через Web-браузер HTTP-запрос в приложение.
  2. Контейнер получает HTTP-запрос и создает объект запроса, содержащий информацию из HTTP-запроса. Контейнер также создает объект ответа, который могут обрабатывать различные фильтры, чтобы подготовить HTTP-ответ для запросившего клиента. Затем контейнер вызывает прокси цепочки фильтрации Acegi, являющийся прокси-фильтром. Этот прокси знает последовательность реальных фильтров, которые нужно применить в цепочке. Когда контейнер вызывает прокси, он передает ему объект-запрос, объект-ответ и цепочку фильтрации.
  3. Прокси-фильтр вызывает первый фильтр в цепочке фильтрации, передавая ему объект-запрос, объект-ответ и цепочку фильтрации.
  4. Фильтры в цепочке последовательно выполняют свои задачи. Фильтр может прервать свою работу в любой момент, вызвав следующий фильтр из цепочки. Фильтр даже может вообще отказаться от обработки, например, APF-фильтр может прервать выполнение своей задачи, если обнаружится, что входящему запросу не требуется аутентификация.
  5. После того как аутентифицирующие фильтры завершают обработку, они передают объекты запроса и ответа в перехватывающий фильтр, настроенный для этого приложения.
  6. Перехватывающий фильтр решает, является ли запрашивающий клиент авторизованным для доступа к запрашиваемому ресурсу.
  7. Перехватывающий фильтр передает управление приложению, например, JSP-странице, запрошенной клиентом, в случае успешной аутентификации и авторизации.
  8. Приложение записывает содержимое в возвращаемый объект-ответ (response).
  9. Теперь объект-ответ готов. Контейнер превращает объект-ответ в HTTP-ответ и отправляет этот ответ запросившему клиенту.

Для лучшего понимания фильтров Acegi мы детально разберем функционирование двух из них: фильтра для интеграции сеанса (SIF - Session Integration Filter) и фильтра для выполнения аутентификации (APF - Authentication Processing Filter).

Как SIF-фильтр создает контекст безопасности

Рисунок 2. SIF-фильтр создает контекст безопасности

Figure 2. SIF creates a security context
How SIF creates a security context

Теперь подробно разберем эти действия:

  1. Прокси-фильтр цепочки фильтрации Acegi вызывает SIF-фильтр и передает ему объекты запроса, ответа и цепочки фильтрации. Отметим, что обычно SIF-фильтр настраивается как первый фильтр в цепочке фильтрации.
  2. SIF-фильтр проверяет, обрабатывался ли уже этот Web-запрос или нет. Если он обнаруживает, что запрос уже обрабатывался, то никакой обработки не выполняется и управление передается следующему фильтру в цепочке фильтрации (см. шаг 4 ниже). Если SIF-фильтр обнаруживает, что он был вызван впервые во время текущего Web-запроса, то устанавливается флаг, который будет использоваться в следующий раз, чтобы отметить что SIF-фильтр уже вызывался.
  3. SIF-фильтр проверяет, существуют ли объект сеанса, и находится ли в нем контекст безопасности. Он извлекает контекст безопасности из объекта сеанса и помещает его во временное хранилище, называемый контейнером контекста безопасности (security context holder). Если объект сеанса еще не существует, то SIF-фильтр создает новый контекст безопасности и помещает его в соответствующий контейнер. Отметим, что контейнер контекста безопасности хранится на уровне приложения, так что он оказывается доступным другим фильтрам безопасности.
  4. SIF-фильтр вызывает следующий фильтр в цепочке фильтрации.
  5. Другие фильтры могут редактировать контекст безопасности.
  6. После того, как цепочка фильтрации завершает обработку, управление передается SIF-фильтру.
  7. SIF-фильтр проверяет, изменяли ли другие фильтры контекст безопасности во время своей работы. Например, APF-фильтр может сохранить информацию о пользователе в контекст безопасности. Если это так, он обновляет контекст безопасности в сеансе. Это значит, что любые изменения, сделанные в контексте безопасности во время работы цепочки фильтрации, теперь будут храниться в объекте сеанса.

Как APF-фильтр выполняет аутентификацию пользователя

На рисунке 3 показаны действия, выполняемые APF-фильтром для аутентификации пользователя:

Рисунок 3. APF-фильтр выполняет аутентификацию пользователя
Рисунок 3. APF-фильтр выполняет аутентификацию пользователя

Теперь рассмотрим эти действия в подробностях:

  1. Предыдущий фильтр в цепочке фильтрации передают объект-запрос, ответ и цепочку фильтрации APF-фильтру.
  2. APF-фильтр создает параметр для аутентификации, используя имя пользователя, пароль и другую информацию, извлеченную из объекта-запроса.
  3. APF-фильтр передает параметр для аутентификации менеджеру аутентификации.
  4. Менеджер аутентификации может содержать один или несколько провайдеров аутентификации. Каждый провайдер поддерживает один тип аутентификации. Менеджер проверяет, какой из провайдеров поддерживает параметр для аутентификации, полученный из APF-фильтра.
  5. Менеджер аутентификации передает параметр для аутентификации провайдеру, который подходит для выполнения требуемого вида аутентификации.
  6. Провайдер аутентификации извлекает имя пользователя из параметра аутентификации и передает его в службу кэширования пользователей. Инфраструктура Acegi поддерживает кэш аутентифицированных пользователей. При следующем входе пользователя в систему Acegi может загрузить информацию о нем - имя пользователя, пароль и права доступа - из кэша, а не из серверного хранилища данных. Такой подход повышает производительность.
  7. Служба кэширования пользователей проверяет, имеется ли в кэше информация об этом пользователе.
  8. Служба кэширования пользователей возвращает провайдеру аутентификации информацию о пользователе. Если в кэше нет информации о пользователе, то возвращается null.
  9. Провайдер аутентификации проверяет, какое значение было возвращено из кэша пользователей: информация о пользователе или null.
  10. Если из кэша был получен null, то провайдер аутентификации передает имя пользователя, извлеченное на шестом шаге, в другую службу - службу получения информации о пользователе.
  11. Служба получения информации о пользователе взаимодействует с хранилищем данных на стороне сервера, например службой каталогов, содержащей информацию о пользователе.
  12. Служба получения информации о пользователе возвращает данные о пользователе или выдает исключительную ситуацию в процессе аутентификации, если найти информацию о пользователе не удается.
  13. Если из кэша пользователей или из службы получения информации возвращается информация о найденном пользователе, то провайдер аутентификации сравнивает параметр аутентификации, например, пароль, предоставленный пользователем, с паролем из возвращенной информации. Если они совпадают, то провайдер аутентификации возвращает информацию о пользователе менеджеру аутентификации. В противном случае в процессе аутентификации выдается исключительная ситуация.
  14. Менеджер аутентификации возвращает информацию о пользователя обратно в APF-фильтр. Пользователь успешно аутентифицирован.
  15. APF-фильтр сохраняет информацию о пользователе в контекст безопасности, созданный на третьем этапе рисунка 2.
  16. APF-фильтр передает управление следующему фильтру в цепочке.

Простое Acegi-приложение

Мы уже достаточно детально познакомились с Acegi, так что в заключение разберем пример, использующий все полученные знания. Для демонстрации накопленных знаний я разработал приложение-пример (см. раздел Материалы для скачивания) и настроил Acegi для защиты некоторых ресурсов этого приложения.

Приложение-пример содержит пять JSP страниц: index.jsp, protected1.jsp, protected2.jsp, login.jsp, и accessDenied.jsp.

Страница index.jsp - это входная страница приложения. На ней пользователю предлагаются три ссылки, как показано на рисунке 4:

Рисунок 4. Входная страница приложения-примера
Рисунок 4. Входная страница приложения-примера

Две ссылки, показанные на рисунке 4, ведут на защищенные ресурсы (protected1.jsp и protected2.jsp), третья ссылка ведет на страницу входа в систему (login.jsp). Страница accessDenied.jsp показывается только в случае, если Acegi решает, что пользователь не авторизован для доступа к защищенному ресурсу.

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

Пользователь может сразу запросить страницу входа в систему, нажав на третью ссылку (Login) на входной странице. В этом случае приложение отобразит страницу входа в систему, где пользователь сможет зарегистрироваться. После регистрации приложение перенаправит пользователя на страницу protected1.jsp, которая является ресурсом по умолчанию, отображаемым в случае, если пользователь вошел в систему без запроса конкретной защищенной страницы.

Настройка приложения-примера

Исходный код для этой статьи содержит конфигурационный XML-файл с именем acegi-config.xml, содержащий конфигурацию фильтров Acegi. Эта конфигурация уже должна показаться вам знакомой по примерам из раздела про фильтры безопасности.

Также необходимо подготовить файл web.xml для приложения-примера, как показано в листинге 8:

Листинг 8. Файл web.xml для приложения-примера
<web-app>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/acegi-config.xml</param-value>
    </context-param>
    <filter>
        <filter-name>Acegi Filter Chain Proxy</filter-name>
        <filter-class>
            org.acegisecurity.util.FilterToBeanProxy
        </filter-class>
        <init-param>
            <param-name>targetClass</param-name>
            <param-value>
                org.acegisecurity.util.FilterChainProxy
            </param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>Acegi Filter Chain Proxy</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
</web-app>

В файле web.xml присутствует следующая конфигурация:

  • URL-путь к файлу acegi-config.xml в теге <context-param>.
  • Название прокси-класса цепочки фильтрации Acegi в теге <filter>.
  • Связывание URL-адресов с фильтром Acegi Filter Chain Proxy в теге <filter-mapping>. Если нужно привязать все URL-адреса приложения к фильтру, можно использовать URL шаблон - /*. Acegi обеспечивает безопасность для всех URL-адресов, связанных с прокси-фильтром цепочки фильтрации Acegi.
  • Загрузчик контекста приложения в теге <listener>, загружающий IOC среды Spring.

Установка и запуск приложения

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

  1. 1. Скопировать файл the acegisample.war из скачанного исходного кода к этой статье в каталог webapps сервера Tomcat, установленного на компьютере.
  2. 2. Потребуется загрузить и разархивировать файл acegi-security-1.0.3.zip с Web-страницы системы безопасности Acegi. В этом архиве находится пример приложения в файле acegi-security-sample-tutorial.war. Разархивируйте war-файл и извлеките все jar-файлы из папки WEB-INF/lib. Потом необходимо скопировать все jar-файлы из папки WEB-INF/lib в папку WEB-INF/lib приложения theacegisample.war.

Теперь можно открыть приложение-пример. Для этого нужно запустить Tomcat и открыть в Web-браузере следующий URL-адрес: http://localhost:8080/acegisample/.

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


Заключение

В первой статье серии Обеспечение безопасности Java-приложений с помощью Acegi были рассмотрены функциональность, архитектура и компоненты системы безопасности Acegi. Были частично разобраны фильтры безопасности Acegi, являющиеся ключевым компонентом каркаса безопасности. Также было показано, как настроить зависимости между компонентами с помощью конфигурационного XML-файла и как фильтры безопасности Acegi работают в примере приложения, реализующего безопасность на основе URL-адресов.

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


Загрузка

ОписаниеИмяРазмер
исходный код для этой статьиj-acegi1.zip10KB

Ресурсы

Научиться

Получить продукты и технологии

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Технология Java
ArticleID=294966
ArticleTitle=Обеспечение безопасности Java-приложений с помощью Acegi: Часть 1. Обзор архитектуры и фильтров безопасности
publish-date=03142008