Продолжим цикл статей, посвященных настройке аутенфикации веб-приложений с использованием SSO JA-SIG CAS. В этой статье предлагается рассмотреть, каким образом настроить веб-приложение, в основе которого лежит Spring Framework 3-й версии.
Spring Framework стал одним из стандартов де-факто в разработке корпоративных веб-приложений. Вышедшая не так давно, 3-я версия этого замечательного фреймворка позволила сделать процесс разработки еще более простым и увлекательным. Как можно будет убедиться, интеграция Spring Framework и JA-SIG CAS не займет много времени и не потребует особых усилий.
Скорее всего вам уже известно, что вопросами аутенфикации и разграничения доступа в Spring Framework отдано на откуп отдельной подсистеме - Spring Security. В третьей версии Spring интеграция с Security стала еще более плотной. На момент написания статьи актуальной является версия 3.0.3.RELEASE (репутация более молодых версий подпорчена неприятным security багом). Для того чтобы избежать проблем с зависимостями библиотек, настойчиво рекомендую использовать для java-разработки apache maven. В этом случае, для подключения Spring Security и CAS, достаточно будет указать в разделе dependencies файла pom.xml следующие блоки:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-cas-client</artifactId>
<version>${org.springframework.version}</version>
</dependency>
Не забудьте определить значение переменной ${org.springframework.version} в разделе properties.
Как можно видеть, от стандартной конфигурации зависимостей Spring Security, указанная выше, отличается наличием дополнительного модуля spring-security-cas-client. Данная библиотека содержит все классы, необходимые для интеграции Spring Security и JA-SIG CAS.
В работе SSO аутенфикации активно используется механизм сессий. Это приводит к необходимости внести определенные изменения в порядок обработки http-запросов. Нашей следующей целью становится файл web.xml. Рекомендуется добавить следующие определения к стандартной конфигурации:
<filter>
<filter-name>CAS Single Sign Out Filter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-mapping>
</filter-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-mapping>
</filter-mapping>
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
После редактирования данных файлов наступает самый объемный этап работы, а именно, формирование файла конфигурации Spring Security. Общепринятым названием для данного файла является securityContext.xml. Последние версии Spring Security опираются на собственное именное пространство конфигурации, а также на настройки по-умолчанию, что позволяет довольно быстро и в лаконичной форме получать работоспособную систему разграничения доступа и аутенфикации. Перепробовав несколько различных конфигураций, я пришел к следующему рабочему варианту:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<security:http entry-point-ref="casEntryPoint">
<security:intercept-url pattern="/admin" access="ROLE_ADMIN"/>
<security:intercept-url pattern="/login" access="ROLE_USER"/>
<security:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<!--suppress SpringModelInspection -->
<security:custom-filter position="CAS_FILTER" ref="casFilter"/>
<security:logout invalidate-session="true" logout-url="/logout" logout-success-url="/"/>
</security:http>
<bean id="casEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<property name="loginUrl" value="https://cas.server.net:8443/login"/>
<property name="serviceProperties" ref="serviceProperties"/>
</bean>
<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
<property name="service" value="http://my_spring_service/j_spring_cas_security_check"/>
<property name="sendRenew" value="true"/>
</bean>
<bean id="casFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="casAuthenticationProvider"/>
</security:authentication-manager>
<bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<property name="userDetailsService" ref="userService"/>
<property name="serviceProperties" ref="serviceProperties"/>
<property name="ticketValidator">
<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<constructor-arg index="0" value="https://cas.server.net:8443/"/>
</bean>
</property>
<property name="key" value="an_id_for_this_auth_provider_only"/>
</bean>
<bean id="userService" class="class that implements spring userService">
</bean>
</beans>
Головным блоком, определяющим настройки Spring Security, является <security:http>. Для данного блока мы указываем точку аутенфикации, перечисляем роли доступа для тех или иных частей ресурса, добавляем cas-filter, и url выхода. Так в данном конфигурационном файле указано, что точка аутенфикации описывается компонентой casEntryPoint, раздел /admin требует от пользователя роли администратора, /login - роли пользователя, остальные части ресурса доступны для анонимных пользователей. Добавление casFilter необходимо для успешной обработки квитанции, получаемой от CAS сервера в случае успешной аутенфикации. Если перейти по url "/logout", то произойдет инвалидация сессии, и пользователь, став анонимным, перенаправляется в корень приложения.
Компонент casEntryPoint определяет url страницы аутенфикации CAS-сервера (https://cas.server.net:8443/login), а также, через компонент serviceProperties, определяет url, который в случае удачной аутенфикации получит квитанцию от CAS-сервера. Данный url прослушивает CAS filter и по-умолчанию равен /j_spring_cas_security_check. Если есть необходимость изменить значение по-умолчанию, это можно сделать, указав соответствующее значение параметру filterProcessUrl бина casFilter.
Основную роль в методе аутенфикации играет экземпляр провайдера аутенфикации. Фильтр CAS узнает о провайдере опосредованно, через ссылку на authenticationManager. Провайдеру необходимо указать способ проверки квитанции, полученной от CAS-сервера (Cas20ServiceTicketValidator), ключ идентификации, а также ссылку на экземпляр UserDetailsService. В моем случае, я использовал самописный UserDetailsService, который создавал экземпляр класса UserDetails с необходимыми ролями и списком переменных для приложения.
В конце, можно запустить приложение и проверить работоспособность аутенфикации через сервер CAS. Хотелось бы напомнить, что для успешного общения с CAS-сервером по протоколу SSL необходимо доверительное отношение к сертификату сервера. В случае, если ваш сертификат самоподписной, не забудьте импортировать его в хранилище сертификатов java-виртуальной машины клиента. Как это делается, описано в предыдущей статье.
Данная конфигурация проста и незатейлива, рассчитана на ситуацию, когда у приложения есть анонимные пользователи с общим доступом, и залогиненные пользователи (например, для предоставления дополнительных функций). Разграничение на основе списков доступа, и более сложные механизмы не рассматривались, но добавление данных возможностей в представленную конфигурацию не должно сильно отличаться от других ситуаций использования Spring Security.
Предыдущие статьи про настройку JA-SIG CAS:
- Начальная сборка CAS-сервера;
- Собственный обработчик аутенфикации CAS-сервера;
- Настройка SSL в Apache Tomcat 6.
Комментариев нет:
Отправить комментарий