Search code examples
springspring-securityaccess-denied

Spring security error with access-denied-handler tag


I added the access-denied-handler tag to redirect to an specific page when my app handles a AccessDeniedException but I have the error:

Configuration problem: Failed to import bean definitions from relative location [pgm-security-cas.xml] Offending resource: class path resource [spring/pgm-servlet.xml]; nested exception is org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 92 in XML document from class path resource [spring/pgm-security-cas.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting with element 'sec:access-denied-handler'. One of '{"http://www.springframework.org/schema/security":intercept-url}' is expected.

this is my xml:

<bean id="fsi"
    class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
    <property name="authenticationManager" ref="authenticationManager" />
    <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager" />
    <property name="securityMetadataSource">
        <sec:filter-invocation-definition-source use-expressions="true">
            <sec:intercept-url pattern="/manageboxes" access="hasRole('A_READ_USER')" />
            <sec:access-denied-handler error-page="/accessDeniedPage" />
        </sec:filter-invocation-definition-source>
    </property>
</bean>

Somebody knows where is problem?

The definition of the filterChainProxy is:

<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
    <sec:filter-chain-map request-matcher="ant">
        <sec:filter-chain pattern="/xhtml/login/invalidLogin.xhtml*" filters="none" />
        <sec:filter-chain pattern="/j_spring_security_logout"
            filters="logoutFilter,fsi" />
        <sec:filter-chain pattern="/javax.faces.resource/*"
            filters="none" />
        <sec:filter-chain pattern="/**"
            filters="casAuthenticationFilter, casValidationFilter, wrappingFilter, sif, j2eePreAuthFilter, logoutFilter, fsi" />
    </sec:filter-chain-map>
</bean>

Solution

  • <access-denied-handler> can't be placed inside <filter-invocation-definition-source>. You have to create an exceptionTranslator:

    <bean id="exceptionTranslator"            class="org.springframework.security.web.access.ExceptionTranslationFilter">
    <property name="authenticationEntryPoint">
        <bean class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"
                p:loginFormUrl="/login" />
    </property>
    <property name="accessDeniedHandler">
        <bean class="org.springframework.security.web.access.AccessDeniedHandlerImpl"
        p:errorPage="/accessDenied" />
    </property>
    </bean> 
    

    and wire it into your filterChainProxy

    <bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
        <sec:filter-chain-map request-matcher="ant">
            <sec:filter-chain pattern="/**"
                filters="casAuthenticationFilter, casValidationFilter, wrappingFilter, sif,      j2eePreAuthFilter, logoutFilter, 
                exceptionTranslator,
                fsi" />
            </sec:filter-chain-map>
    </bean>