Я нашел решение. Если кому-то интересно, я объясню здесь.
Я добавил следующий Java-код в метод doFilter в своем фильтре управления сеансом, чтобы проверить, разрешен ли пользователю (в данном случае анонимному пользователю) доступ к запрашиваемой странице:
...
private WebInvocationPrivilegeEvaluator webPrivilegeEvaluator;
...
// Before this I have checked that the session is invalid and that the invalidSessionUrl parameter isn't null
String uri = request.getRequestURI();
String cPath = request.getContextPath();
int longCPath = cPath.length();
String pagSolicitada = uri.substring(longCPath);
Authentication autenticacion = SecurityContextHolder.getContext().getAuthentication();
if ( !webPrivilegeEvaluator.isAllowed(pagSolicitada, autenticacion) ) {
// Redirect to the invalidSessionUrl
redirectStrategy.sendRedirect(request, response, invalidSessionUrl);
return;
}
// Do nothing, just skip this filter
chain.doFilter(request, response);
return;
...
webPrivilegeEvaluator является свойством фильтра управления сеансом, который я вставляю в файл конфигурации xml:
<beans:bean id="filtroGestionSesion" class="springSecurity.FiltroGestionSesion">
<beans:constructor-arg name="securityContextRepository" ref="securityContextRepository" />
<beans:property name="sessionAuthenticationStrategy" ref="sas" />
<beans:property name="invalidSessionUrl" value="/faces/paginas/autenticacion/login.xhtml?error=timeout" />
<beans:property name="webPrivilegeEvaluator" ref="webPrivilegeEvaluator" />
</beans:bean>
И bean-компонент, на который ссылается это свойство:
<beans:bean id="webPrivilegeEvaluator" class="org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator">
<beans:constructor-arg ref="filterSecurityInterceptor" />
</beans:bean>
Наконец, filterSecurityInterceptor имеет элементы intercept-url с шаблонами и требуемым для них доступом (вы не помещаете эти intercept-url в http-элемент NameSpace, просто помещаете их здесь):
<beans:bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<beans:property name="securityMetadataSource">
<filter-security-metadata-source use-expressions="true">
<!-- IMPORTANTE: Poner las URLs más específicas primero -->
<intercept-url pattern="/" access="permitAll"/> <!-- Página inicio al arrancar la aplic (contextPath) -->
<intercept-url pattern="/faces/inicio.xhtml" access="permitAll"/>
<intercept-url pattern="/faces/paginas/autenticacion/login.xhtml*" access="permitAll"/>
<intercept-url pattern="/faces/paginas/autenticacion/**" access="isAuthenticated()"/>
<intercept-url pattern="/faces/paginas/administracion/**" access="isAuthenticated()"/>
<intercept-url pattern="/faces/paginas/barco/**" access="isAuthenticated()"/>
<intercept-url pattern="/faces/paginas/catalogo/**" access="permitAll"/>
<intercept-url pattern="/faces/paginas/error/**" access="permitAll"/>
<intercept-url pattern="/faces/paginas/plantillas/**" access="permitAll"/>
<intercept-url pattern="/**" access="denyAll" />
</filter-security-metadata-source>
</beans:property>
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="accessDecisionManager" ref="httpRequestAccessDecisionManager" />
<beans:property name="observeOncePerRequest" value="false" />
</beans:bean>
Этот фильтр должен быть объявлен как последний из цепочки фильтров, таким образом:
<custom-filter position="LAST" ref="filterSecurityInterceptor" />
ПРИМЕЧАНИЕ. Я намеренно опустил объявления других bean-компонентов, чтобы этот ответ не был слишком большим.