JSF - проблема интеграции Spring Security - PullRequest
1 голос
/ 07 февраля 2012

API Servlet 2.4+ позволяет нам использовать тег <dispatcher> внутри тега <filter-mapping> со значениями, такими как FORWARD, для перехвата запросов, внутренне перенаправляемых на другие ресурсы. Для пересылки одного сервлета на другой пружинные ограничения безопасности работают нормально.

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>    

Проблема: Фильтр безопасности НЕ перехватывает внутренние пересылки с помощью JSF Actions

JSF, кажется, «перенаправляет» запрос к целевому представлению (странице) при использовании действий JSF (случай навигации). Это приводит к тому, что URL-адрес на один шаг отстает от фактического URL-адреса страницы.

Побочным эффектом этого является то, что пружинное ограничение безопасности (которое связано с URL) не вступает в силу до следующего действия.

Пример: URL текущей страницы: http://host/myapp/page1.xhtml (page1.xhtml имеет действие, которое переходит на страницу page2, которая защищена)

При отправке запрос отправляется на сервер, который отображает page2.xhtml, но URL все еще остается как http://host/myapp/page1.xhtml. Spring Security не перехватывает и не защищает page2.xhtml

Это можно преодолеть, указав следующее:

<navigation-case>
    <from-outcome>page2</from-outcome>
    <to-view-id>/page2.xhtml</to-view-id>
    <redirect/> <!--REDIRECT, INSTEAD OF FORWARD-->
</navigation-case>

Перенаправление НЕ является тем способом, которым мы хотим достичь этого. Есть ли лучший способ заставить Spring Security работать с JSF?

РЕДАКТИРОВАТЬ: (соответствующий фрагмент конфигурации пружины XML)

<http use-expressions="true" once-per-request="false">
    <intercept-url pattern="/index.xhtml" access="permitAll" />
    <intercept-url pattern="/page1.xhtml" access="isAuthenticated()" />
    <intercept-url pattern="/page2.xhtml" access="hasRole('supervisor')" />
    <intercept-url pattern="/page3.xhtml" access="hasRole('teller')" />
    <form-login  login-page="/login.html" default-target-url="/page1.xhtml"/>
</http>

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="rod" password="rod" authorities="supervisor,  user" />
            <user name="dianne" password="dianne" authorities="teller, user" />
            <user name="scott" password="scott" authorities="supervisor" />
            <user name="peter" password="peter" authorities="user" />
        </user-service>
    </authentication-provider>
</authentication-manager>

Ответы [ 2 ]

1 голос
/ 08 февраля 2012

Из уст лошади (документация оракула)

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

То, на что это похоже, заключается в том, что в течение жизненного цикла JSF не происходит «пересылка» на следующую страницу ... и поэтому Spring Security никогда не справится с этим.

0 голосов
/ 02 июля 2012

По умолчанию FilterSecurityInterceptor будет выполняться только один раз на запрос и не будет выполнять повторную проверку безопасности, если в URL не произошли изменения, но при переадресации JSP / JSF страница отображается как ответ на текущий запрос и URL в браузере содержит адрес предыдущей страницы. Поэтому для этого просто установите для атрибута «один раз на запрос» значение false в элементе http в applicationContext, что приведет к повторной проверке безопасности.

<http auto-config="true" use-expressions="true" once-per-request="false">

и добавьте диспетчер для форвардов в сопоставлении фильтра springSecurityFilterChain в вашем файле web.xml

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

Подробнее info

В качестве альтернативы, вы также можете включить перенаправление страниц, добавив параметр face-redirect = true к результату следующим образом:

<h:form>
    <h:commandButton action="page1?faces-redirect=true" value="Page1" />
</h:form>

Но, как BalusC говорит, что не хорошая практика использовать POST для постраничной навигации. Всегда делай GET используя

<h:link> or <h:button>

Также см .:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...