Главная » Spring » Отображение с учетом привилегий Spring

0

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

Тег <security:authorize> позволяет отображать фрагменты пред- ставлений в зависимости от привилегий, которыми обладает поль- зователь. Например, в приложении Spitter форма добавления нового сообщения не должна отображаться, если пользователь не обладает привилегией ROLE_SPITTER. Листинг 10.5 демонстрирует, как с помощью

тега <security:authorize>  обеспечить отображение формы ввода сооб- щения, только если пользователь обладает привилегией ROLE_SPITTER.

Листинг 10.5. Отображение содержимого по условию с помощью тега

<security:authorize>

<sec:authorize access="hasRole(‘ROLE_SPITTER’)">     <!– Только при обладании –>

<!– привилегией ROLE_SPITTER –>

<s:url value="/spittles" var="spittle_url" />

<sf:form  modelAttribute="spittle" action="${spittle_url}">

<sf:label  path="text"><s:message code="label.spittle" text="Enter    spittle:"/></sf:label>

<sf:textarea  path="text"  rows="2"  cols="40"  />

<sf:errors  path="text"  />

<br/>

<div   class="spitItSubmitIt">

<input type="submit" value="Spit it!" class="status-btn round-btn disabled" />

</div>

</sf:form>

</sec:authorize>

В атрибуте access указано выражение на языке SpEL, результат кото- рого определяет, будет ли отображаться тело тега <security:authorize>. Здесь используется выражение hasRole(‘ROLE_SPITTER’), проверяющее, обладает ли текущий пользователь привилегией ROLE_SPITTER. Но точ- но так же в атрибуте access можно использовать любые выражения на языке SpEL, включая выражения, перечисленные в табл. 10.2 и имеющие непосредственное отношение к системе безопасности.

С помощью этих выражений можно реализовать весьма интерес- ные ограничения. Например, представьте, что приложение включает некоторые административные функции, которые должны быть до- ступны лишь пользователю habuma. Для определения ограничения можно было бы использовать выражения isAuthenticated() и principal, как показано ниже:

<security:authorize

access="isAuthenticated()   and   principal.username==’habuma’">

<a  href="/admin">Administration</a>

</security:authorize>

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

Но в примере, который я придумал, есть одна лазейка. Несмотря на возможность предоставить доступ к административным функ- циям только пользователю habuma, реализация такого ограниче- ния с использованием выражения на языке SpEL далека от идеала. Разумеется, ссылка с адресом административной страницы не будет отображаться перед другими пользователями, но ничто не мешает им вручную ввести URL /admin в адресной строке браузера.

Вспомнив, о чем рассказывалось в этой главе, мы легко можем исправить данную проблему, достаточно лишь добавить новый эле- мент <intercept-url> в настройки безопасности, ограничивающий до- ступ к URL /admin:

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

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

Теперь административные функции будут надежно заперты от по- сторонних. Сам URL будет доступен только одному пользователю, и ссылка с этим адресом не будет появляться перед пользователем, не обладающим соответствующими полномочиями. Но, чтобы до- биться этого, пришлось объявить одно и то же выражение на языке SpEL в двух местах – в элементе <intercept-url> и в атрибуте access тега <security:authorize>. А возможно ли организовать отображение URL только при выполнении требований безопасности, определяе- мых для него?

Возможно, с помощью атрибута url тега <security:authorize>. В от- личие от атрибута access, где ограничения определяются явно, атри- бут url неявно ссылается на ограничения, накладываемые на шаблон URL. Поскольку ограничения безопасности для URL /admin уже определены в конфигурационном файле Spring Security, мы можем использовать атрибут url, как показано ниже:

<security:authorize  url="/admin/**">

<spring:url   value="/admin"   var="admin_url"   />

<br/><a  href="${admin_url}">Admin</a>

</security:authorize>

Поскольку доступ к URL /admin может получить только аутенти- фицированный пользователь с привилегией ROLE_ADMIN и только ес- ли запрос приходит с определенного IP-адреса, тело тега <security: authorize> будет отображаться, только если выполняются все эти требования.

Другие атрибуты тега <security:authorize>. Помимо атрибутов access и url, тег <security:authorize> имеет еще три атрибута: ifAllGranted, ifAnyGranted и ifNotGranted. Эти атрибуты тега <security:authorize> позво- ляют обеспечить отображение информации в зависимости от наличия или отсутствия привилегий у пользователя.

До версии Spring Security 3.0 эти три атрибута были единственными, до- ступными в теге <security:authorize>. Но с введением поддержки языка выражений SpEL и атрибута access они потеряли актуальность. Их все еще можно использовать, но с помощью атрибута access можно реализовать то же самое и даже больше.

Теперь мы знаем, как реализовать различные ограничения на уровне представлений. Остается выяснить один вопрос: где хранит- ся информация о пользователе? Иными словами: когда кто-то пы- тается аутентифицироваться в приложении, откуда Spring Security возьмет информацию для сравнения с данными аутентификации, представленными пользователем?

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

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

По теме:

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