Использование intercept-url в Spring безопасности - программирование
Подтвердить что ты не робот

Использование intercept-url в Spring безопасности

Каков предпочтительный способ создания шаблонов в элементе intercept-url в Spring безопасности? Я создаю веб-службу (RESTful), и в настоящее время я требую, чтобы все пользователи вошли в систему и имели роль ROLE_USER. Затем дополнительные ограничения выполняются аннотациями @PreAuthorize на уровне службы. Однако общепринято также добавлять несколько элементов intercept-url, которые имеют разную конфигурацию?

4b9b3361

Ответ 1

Я должен думать, что "предпочтительный путь" [обязательно] субъективен. У меня были <intercept-url> элементы в security.xml, но они оставили их в пользу аннотаций @RequestMapping с @PreAuthorize на контроллерах. Это чисто личное предпочтение (в моем случае), поскольку я предпочитаю хранить вещи в Java, а не в пространствах имен XML, насколько это возможно.

Вы можете использовать один, другой или оба, и вы можете сделать аннотацию для улучшения XML - вы можете, например, иметь что-то вроде следующего:

security.xml

<intercept-url pattern="/something" access="hasRole('ROLE_USER')"/>

YourController.java

@RequestMapping(value="/something/else")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public String getSomethingElseContents(){ return "somethingelse"; }

Как я уже сказал, кажется, что это просто вопрос предпочтения. Преимущество использования пространства имен XML заключается в том, что правила базового доступа находятся в одном месте, легко читаются и легко отслеживаются. Правила, налагаемые @PreAuthorize (или другими вариантами аннотации), особенно сексуальны, потому что вы можете называть свое собственное выражение SpEL в них и основывать свое разрешение на доступе к переданным параметрам или полям, доступным классу (т.е. @PreAuthorize("@my.project.package.hasMagicPower(#power.INVISIBILITY)")), или их комбинаций. Вы можете применять логические и динамические разрешения, которые в противном случае недоступны для параметра пространства имен.

Конечно, вы можете применять рудиментарную логику с помощью "и", "или" и "!". Связи в выражениях SpEL в пространстве имен (и вы можете получить доступ к внешним классам [логическим] методам с помощью указателя @ в XML), но все, указанное в XML, должно быть статическим.


tl; dr: предпочтение отдается личным предпочтениям, но если вам нужна или нужна динамическая гибкость в обработке разрешений, вы должны использовать аннотации. Если вы не хотите и не нуждаетесь в динамической гибкости, у вас есть опция (и звуковой аргумент подсказывает, что опция пространства имен лучше по отношению к SoC). Я предпочитаю, чтобы Java обрабатывал его для гибкости, и поскольку, как только я настроил свой XML, я хочу оставить его в покое и сосредоточиться на Java. Кроме того, существует несколько убедительный контраргумент представления SoC, который заключается в том, что правильно написанное Java-приложение будет иметь свои контроллеры в легкодоступных пакетах с явным контролем по имени.


еще tl; dr: Мех. Шесть из них, полдюжины других. Я говорю po-tay-to.

Ответ 2

Большинство веб-приложений, использующих Spring Безопасность, имеют только пару intercept-url, потому что у них есть только самые основные требования безопасности. Вам необходимо иметь неавторизованный доступ к экранам входа и входа в систему и, как правило, к некоторым аспектам публичного сайта, так что это может быть несколько шаблонов URL. Тогда часто есть раздел администратора, а затем все остальное ROLE_USER.

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

<http realm="Contacts Realm" use-expressions="false">
    <intercept-url pattern="/index.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/admin/*" access="ROLE_ADMIN"/>
    <intercept-url pattern="/secret/*" access="ROLE_SECRET"/>
    <intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN,ROLE_SECRET"/>
    <http-basic/>
</http>

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

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

Ответ 3

Конфигурация SpringSecurity зависит от выбранной вами аутентификации для вашего приложения: Например, для проверки подлинности формы вы хотите настроить URL-адрес успеха входа и выхода из системы без разрешения:

<http realm="Contacts Realm">
    <intercept-url pattern="/index.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/**" access="ROLE_USER"/>
    <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1"/>
    <logout logout-success-url="/index.jsp"/>
</http>

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

<http realm="Contacts Realm">
    <intercept-url pattern="/**" access="ROLE_USER"/>
    <http-basic/>
</http>

В случае выбора базовой проверки подлинности используйте второй пример.

Ответ 4

Перехват URL-адреса может быть выполнен таким образом. Предположим, что ваши URL-адреса службы обслуживания начинаются с /rest/.

<http auto-config="true" use-expressions="true" access-denied-page="/accessDeniedPageURL">
    <intercept-url pattern="/rest/**" access="hasRole('ROLE_USER')"/>
    <intercept-url pattern="/view/products" access="isFullyAuthenticated()"/>        

    <form-login login-page="/landing" default-target-url="/view/products" authentication-failure-handler-ref="authenticationFailureHandler"/>
    <logout invalidate-session="true" logout-success-url="/landing" delete-cookies="JSESSIONID"/>

    <session-management invalid-session-url="/landing" session-authentication-error-url="/landing?msg=alreadyLogin">
        <concurrency-control max-sessions="1" expired-url="/landing?msg=sessionExpiredDuplicateLogin" error-if-maximum-exceeded="false"/>
    </session-management>    
</http>

Ответ 5

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

Вы также можете использовать каталог для каждого ограничения, поэтому вам не понадобятся аннотации. Ex./user/** требует ROLE_USER,/admin/** требует ROLE_ADMIN и т.д.

Имейте в виду, когда вы используете любой метод, как он влияет на вашу безопасность, если вы допустили ошибку.

Если вы используете URL-адрес перехвата, вы должны поместить строки в правильном порядке, например:

<intercept-url pattern="/**" access="permitAll"/>
<intercept-url pattern="/user/**" access="hasRole('ROLE_USER')"/>

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

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

@PreAuthorize("hasRole('ROLE_USER')")

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

Так что имейте в виду, @PreAuthorize будет жестко закодирован и распространен среди проектов. Вы можете расширить классы и добавить разные @PreAuthorize для каждого проекта, но это добавляет дополнительную сложность.

Мне нравится использовать intercept-url для защиты всей области, например /user/ **, потому что риск удаления аннотации меньше по ошибке.

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

Ответ 6

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

Альтернативой является использование перехватчиков запросов. В нескольких проектах для служб RESTful, использующих Spring MVC, я использую Interceptors Request для завершения некоторой аутентификации вне основного доступа к ролям. Это работает, и, на мой взгляд, намного проще отслеживать цепочку событий, но если вы имеете дело с тысячами транзакций в минуту, это может заглушить запросы.