The Servlet 2.4+ API allows us to use the <dispatcher>
tag within the <filter-mapping>
tag with values like FORWARD
to intercept requests being internally forwarded to other resources. For one servlet forwarding to another, the spring security constraints work fine.
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
Problem: The security filter does NOT seem to intercept the internal forwards with JSF Actions
JSF seems to 'forward' the request to the target view (page) while using JSF actions (navigation case). This causes the URL to be one step behind the actual URL of the page.
A side effect of this is that the spring security constraint (which is tied to the URL) does not take effect until the next action.
Example: Current page URL: http://host/myapp/page1.xhtml (page1.xhtml has an action that navigates to page2 which is protected)
On submit, the request is submitted to the server which renders page2.xhtml but the URL still remains as http://host/myapp/page1.xhtml. Spring Security does not intercept and protect page2.xhtml
This can be overcome by specifying the following:
<navigation-case>
<from-outcome>page2</from-outcome>
<to-view-id>/page2.xhtml</to-view-id>
<redirect/> <!--REDIRECT, INSTEAD OF FORWARD-->
</navigation-case>
Redirects is NOT the way we want to achieve this. Is there a better way of getting Spring Security to work with JSF?
EDIT: (relevent snippet of the spring config 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>