Главная » Spring » Перехват запросов Spring

0

В предыдущем разделе был представлен простой пример исполь- зования элемента <intercept-url>. Но мы узнали о нем совсем не- много… пока.

Элемент <intercept-url> – это первая линия обороны в системе безопасности. Его атрибут pattern определяет шаблон URL, кото- рый будет сопоставляться с входящими запросами. Если какой-ли- бо запрос совпадет с шаблоном, к нему будут применены правила безопасности, определяемые элементом <intercept-url>.

Вернемся к определению элемента <intercept-url>, представленно- му выше:

<intercept-url pattern="/**" access="ROLE_SPITTER" />

По умолчанию в атрибуте pattern указывается шаблон пути в сти- ле утилиты Ant. Но если атрибуту path-type элемента <http> присво-

ить значение regex, в качестве шаблона пути можно будет использо- вать регулярное выражение.

В данном случае в атрибуте pattern задано значение /**, указы- вающее, что перехватываться должны все запросы, независимо от URL, и для получения доступа к содержимому пользователь должен обладать привилегией ROLE_SPITTER. Шаблон /** имеет широкую об- ласть значений и иногда бывает необходимо ограничить ее.

Представьте, что в приложении Spitter имеются специальные страницы, которые должны быть доступны только администрато- рам. Чтобы ограничить доступ к ним, можно добавить следующий элемент <intercept-url>  перед уже имеющимся:

<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />

Наш первый элемент <intercept-url> гарантирует, что к большей части приложения смогут обращаться только пользователи, обла- дающие привилегией ROLE_SPITTER, а данный элемент <intercept-url> ограничивает доступ к ветви /admin в иерархии сайта, допуская к ней только пользователей с привилегией ROLE_ADMIN.

В файле конфигурации допускается использовать любое коли- чество элементов <intercept-url>, чтобы обезопасить различные пу- ти в веб-приложении. Но важно помнить, что правила, определяе- мые элементами <intercept-url>, применяются в направлении сверху вниз. То есть этот новый элемент <intercept-url> должен находиться перед оригинальным элементом, иначе шаблон пути /** получит бо- лее высокий приоритет.

Настройка безопасности с применением выражений Spring

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

В главе 2 было показано, как использовать язык выражений Spring (Spring Expression Language, SpEL) для связывания свойств компо- нентов. Начиная с версии 3.0, фреймворк Spring Security предостав- ляет возможность использовать SpEL для определения правил до- ступа. Чтобы воспользоваться ею, необходимо определить значение true  в атрибуте use-expressions  элемента <http>:

<http  auto-config="true"  use-expressions="true">

</http>

Теперь можно использовать выражения на языке SpEL в атрибуте access. Ниже показано, как на языке SpEL потребовать наличия при- вилегии ROLE_ADMIN при обращении к адресам, совпадающим с шаб- лоном  /admin/**:

<intercept-url pattern="/admin/**" access="hasRole(‘ROLE_ADMIN’)"/>

Этот элемент <intercept-url> полностью эквивалентен предыду- щему, за исключением того, что в нем используется выражение на языке SpEL. Выражение hasRole() возвращает true, если текущий пользователь обладает указанной привилегией. Но hasRole() – лишь одно из множества поддерживаемых выражений, имеющих отноше- ние к безопасности. В табл. 10.2 перечислены все выражения SpEL, поддерживаемые фреймворком Spring Security 3.0.

Таблица 10.2. Фреймворк Spring Security расширяет язык выражений Spring несколькими дополнительными выражениями

Пространство имен

Назначение

authentication

Объект аутентификации пользователя

denyAll

Всегда возвращает false

hasAnyRole(list_of_roles)

true, если пользователь обладает какой-либо

из привилегий, перечисленных в списке list_of_roles

hasRole(role)

true, если пользователь обладает привилегией role

hasIpAddress(IP  Address)

IP-адрес пользователя (доступен только в веб-приложениях)

isAnonymous()

true, если текущий пользователь не был аутентифицирован

isAuthenticated()

true, если текущий пользователь был аутентифицирован

isFullyAuthenticated()

true, если текущий пользователь был аутентифици- рован и не использовал функцию «запомнить меня»

isRememberMe()

true, если текущий пользователь был аутентифици- рован автоматически

permitAll

Всегда возвращает false

principal

Основной объект, представляющий пользователя

Благодаря поддержке языка выражений SpEL доступ к страницам можно ограничивать, основываясь не только на привилегиях поль- зователя. Например, если доступ к страницам администрирования должен ограничиваться не только наличием привилегии ROLE_ADMIN,

но и определенным IP-адресом, элемент <intercept-url> можно опре- делить, как показано ниже:

<intercept-url pattern="/admin/**"

access="hasRole(‘ROLE_ADMIN’) and hasIpAddress(‘192.168.1.2′)"/>

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

А сейчас познакомимся с еще одной интересной особенностью элемента <intercept-url>: принудительное требование к используе- мому протоколу.

Принудительное использование протокола HTTPS

Передача данных по протоколу HTTP весьма небезопасна. Воз- можно, нет ничего страшного, если текст сообщений в приложении Spitter будет отправляться с помощью открытого протокола HTTP. Но передача секретной информации, такой как пароли и номера кредитных карт, по протоколу HTTP может привести к большим неприятностям. Именно поэтому секретную информацию лучше от- правлять в зашифрованном виде, по протоколу HTTPS.

Задействовать протокол HTTPS довольно просто. Достаточно лишь добавить символ «s» после «http» в URL и все. Правильно?

Да, это так, но при этом вся ответственность за использование протокола HTTPS возлагается на программиста. А теперь пред- ставьте, что в приложении имеются десятки и сотни ссылок и форм, в которых должен быть указан протокол HTTPS. Слишком легко забыть добавить такую важную букву «s». Слишком велика вероят- ность, что программист пропустит ее в одном-двух местах или по ошибке укажет протокол HTTPS там, где в нем нет необходимости.

Атрибут requires-channel элемента <intercept-url> позволяет снять эту ответственность с программиста и переложить ее на конфигу- рацию Spring Security.

Рассмотрим в качестве примера форму регистрации в приложе- нии Spitter. Приложение Spitter не просит указать номер кредит- ной карты, или номер карты социального обеспечения, или что-то жутко секретное, однако пользователи могут пожелать сохранить в тайне информацию о себе. Для этого необходимо настроить эле- мент <intercept-url>, описывающий доступ к адресу /spitter/form, как показано ниже:

<intercept-url  pattern="/spitter/form"   requires-channel="https"/>

Всякий раз, когда приложение будет получать запрос к адресу / spitter/form, фреймворк Spring Security будет обнаруживать требова- ние https к протоколу и автоматически переадресовывать запрос на использование протокола HTTPS. Аналогично для доступа к глав- ной странице приложения не требуется использовать протокол HTTPS, поэтому можно объявить, что доступ к ней всегда должен осуществляться по протоколу HTTP:

<intercept-url pattern="/home" requires-channel="http"/>

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

Источник:   Уоллс К., Spring в действии. – М.: ДМК Пресс, 2013. – 752 с.: ил.

По теме:

  • Комментарии