4

I'm using Spring Security 3.0.7

How can I get with java code the "access" attributes of the "patterns" that I have defined in the <intercept-url> elements of my security configuration file?

I need to get them in my custom session management filter, so that if the requested URL has an ANONYMOUS access required, I skip the filter and don't check the session timeout.

Now I'm doing it "manually", by comparing the requested URL with those patterns I know they have an ANONYMOUS access required. It works, but it's not a good solution because if I change the xml config file, I have to change the java code.

Thank you in advance.

Johan
  • 74,508
  • 24
  • 191
  • 319
choquero70
  • 4,470
  • 2
  • 28
  • 48

1 Answers1

3

I've found the solution. If someone's interested I explain it here.

I added the following Java code to the doFilter method in my session management filter, for checking if the user (anonymous user in this case) is allowed to access the requested page:

...
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;
...

The webPrivilegeEvaluator is a property of the session management filter that I inject in the xml config file:

<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>

And the bean that this property references is:

<beans:bean id="webPrivilegeEvaluator" class="org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator">
    <beans:constructor-arg ref="filterSecurityInterceptor" />
</beans:bean>

Finally, the filterSecurityInterceptor has the intercept-url elements with the patterns and access required for them (you don't put these intercept-url in the http element of the NameSpace, just put them here):

<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>

This filter has to be declared as the last one of the filter chain, this way:

<custom-filter position="LAST" ref="filterSecurityInterceptor" />

NOTE: I've intentionally omitted the declarations of other beans in order to not make this answer too large.

choquero70
  • 4,470
  • 2
  • 28
  • 48
  • I've got a question for choquero70. Do you know if WebInvocationPrivilegeEvaluator has knowledge of @PreAutorize annotations in controller Methods? – Ricardo Vila Mar 04 '15 at 11:11