Я использую Spring 3.1.0 и сталкиваюсь с поведением, которое я бы классифицировал как ошибку. Но я верю, что больше шансов, что это моя вина. Любая помощь очень ценится.
Я успешно выполнил советы по созданию ‹шаблона URL-адреса перехвата ›Динамически с пружинной защитой 3. Итак, я успешно настроил пространство имен http для использования моего собственного securityMetadataSource.
Обратите внимание, что я знаю, что это не рекомендуется. Но тот факт, что он не работает должным образом, заставляет меня чувствовать, что я упускаю что-то важное.
Как описано в связанной теме выше, я удалось правильно настроить следующую конфигурацию:
<http>
<form-login login-page="/login"
default-target-url="/welcome"
always-use-default-target="false"
authentication-failure-url="/login?error=1"
/>
<logout logout-url="/logout.secure" logout-success-url="/" />
<http-basic/>
<custom-filter ref="myFilterSecurityInterceptor"
before="FILTER_SECURITY_INTERCEPTOR" />
</http>
Итак, myFilterSecurityInterceptor использует mySecurityMetadataSource, где я определяю экземпляры SecurityConfig, такие как «ROLE_ADMIN», «IS_AUTHENTICATED_FULLY» и т. Д .; и экземпляры AntPathRequestMatcher для проверки. И это работает: если у пользователя нет заданной роли, доступ запрещается по тем путям, где он требуется.
Проблемы связаны с безопасностью taglib.
Согласно документации Spring по библиотекам тегов безопасности (здесь), чтобы использовать тег <security:authorize>
в контексте вашего приложения также должен быть экземпляр WebInvocationPrivilegeEvaluator. Если вы используете пространство имен, оно будет автоматически зарегистрировано.
При первом вызове <security:authorize url="" >...</security:authorize>
генерируется исключение, поскольку оказывается, что WebSecurityExpressionHandler
реализующий компонент не найден. По сути, мой myFilterSecurityInterceptor
использует mySecurityMetadataSource
, который реализует FilterInvocationSecurityMetadataSource
. Итак, моя реализация фильтра не обрабатывает выражения. И нигде в своей конфигурации я такой боб не объявляю. По сути, я думал, что обработка выражений не потребуется, поскольку я ничего не спрашивал в своем объявлении <http>
и, как сказано в документации выше:
Первый подход использует выражение веб-безопасности, указанное в атрибуте доступа тега. Оценка выражения будет делегирована SecurityExpressionHandler, определенному в контексте приложения (вы должны включить веб-выражения в конфигурации пространства имен, чтобы убедиться, что эта служба доступна). [...] Этот тег также может работать в альтернативном режиме, который позволяет вам определять конкретный URL как атрибут.
Поэтому я считал, что обработка выражений не требуется, поскольку я использовал второй подход с использованием метода <security:authorize>
: url, а не метода доступа.
В любом случае, я могу избежать вышеупомянутого исключения, добавив в объявление <http>
следующий атрибут:
use-expressions="true"
Выполнив это последнее уточнение моей конфигурации, я получаю следующее: 1) моя авторизация на основе ролей (реализованная в mySecurityMetadataSource
и проверка соответствия URL-адреса простым строкам как «ROLE_ADMIN» или «IS_AUTHENTICATED_FULLY») работает правильно, запрещая доступ к URL-адресу, если у пользователя нет необходимой авторизации; 2) теги <security:authorize>
не находят объявленного перехватчика (настройка настраиваемого фильтра в <http>
кажется проигнорированной), поэтому отображается каждая ссылка, независимо от того, какие роли играет пользователь.
Итак, мой вопрос: можно (легко) смешать тег <security:authorize>
с вашим собственным SecurityMetadataSource?
Заранее благодарим вас за любую помощь или подсказку. Чао Алессандро