There are a default set of filters registered when we use the <http>
element in our xml file. This mentions the ordering of filters (whichever we choose to apply), and just above that, it mentions :
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<constructor-arg>
<list>
<sec:filter-chain pattern="/restful/**" filters="
securityContextPersistenceFilterWithASCFalse,
basicAuthenticationFilter,
exceptionTranslationFilter,
filterSecurityInterceptor" />
<sec:filter-chain pattern="/**" filters="
securityContextPersistenceFilterWithASCTrue,
formLoginFilter,
exceptionTranslationFilter,
filterSecurityInterceptor" />
</list>
</constructor-arg>
</bean>
If the above is the list of default filters, then during debugging, I found that RequestCacheAwareFilter
is also called. From where is this filter called and what is its position in the filter chain ? In which condition is AnonymousAuthenticationFilter
configured into the chain ?
What's the default filter chain that's configured for me ?
Edit : I have applicationContext.xml and springSecurity.xml. The following is my applicationContext.xml :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:annotation-config />
<context:spring-configured />
<!-- Make sure that the part of the file until "End of beans" is identical
to bean definitions in applicationContext.xml of the main application. -->
<bean id="adminService" class="org.daud.admin.server.AdminServiceImpl" />
<bean id="feedbackService" class="org.daud.feedback.server.FeedbackServiceImpl" />
<bean id="guideService" class="org.daud.guider.server.GuiderServiceImpl" />
<bean id="messageService" class="org.daud.messages.server.MessageServiceImpl" />
<bean id="wsService" class="org.daud.guider.server.WSServiceImpl" />
<bean id="jabxUtil" class="org.daud.common.server.services.JAXBUtil" />
<bean id="serviceAdvisor" class="org.daud.common.server.ServiceAdvisor" />
<bean id="userPreferences" class="org.daud.preferences.server.UserPreferencesServiceImpl" />
<bean id="dynamicClientFactory" class="org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory" factory-method="newInstance" />
<!-- End of beans. -->
<!-- For testing. -->
<bean id="guiderClientService" class="org.daud.guider.server.GuiderClientServiceImpl" />
<bean id="entityManager" class="com.daud.jpa.DBUtil" factory-method="createEntityManager" lazy-init="true">
<constructor-arg value="bb-test" />
</bean>
<bean id="testUtil" class="com.daud.jpa.JPATestUtil" lazy-init="true">
<constructor-arg ref="entityManager" />
<constructor-arg value="org.daud" />
<constructor-arg value="fixtures" />
</bean>
</beans>
And this is my springSecurity.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<aop:aspectj-autoproxy proxy-target-class="true" />
<beans:bean class="com.gwt.ss.GwtExceptionTranslator" />
<global-method-security secured-annotations="enabled" access-decision-manager-ref="methodSecurityAccessDecisionManager"/>
<http use-expressions="true" auto-config="false" disable-url-rewriting="true" access-decision-manager-ref="urlSecurityAccessDecisionManager">
<intercept-url pattern="/favicon.ico" filters="none" />
<intercept-url pattern="/login.jsp" filters="none" />
<!-- Allow access only to admins and superadmins for the following 2 url patterns -->
<intercept-url pattern="/do/admin/*" access="hasAdminStatus(3,4)" />
<intercept-url pattern="/admin/*" access="hasAdminStatus(3,4)" />
<intercept-url pattern="/**/*.html" access="isAuthenticated()" /> <!-- access="isAuthenticated()"-->
<intercept-url pattern="/do/**" access="isAuthenticated()" />
<intercept-url pattern="/**" access="isAuthenticated()" />
<custom-filter after="FILTER_SECURITY_INTERCEPTOR" ref="switchUserProcessingFilter"/>
<form-login login-page="/login" login-processing-url="/do/login" authentication-failure-url="/login?authfailed=true" authentication-success-handler-ref="myAuthenticationSuccessHandler"/>
<!-- Using success-handler-ref instead of logout-success-url for asynchronous logout. -->
<logout invalidate-session="true" success-handler-ref="logoutSuccessHandler" logout-url="/do/logout" />
</http>
<beans:bean id="urlSecurityAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<beans:property name="decisionVoters">
<beans:list>
<beans:bean class="org.springframework.security.web.access.expression.WebExpressionVoter">
<beans:property name="expressionHandler" ref="myWebSecurityExpressionHandler"/>
</beans:bean>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="myWebSecurityExpressionHandler" class="org.daud.common.server.security.MyWebSecurityExpressionHandler"/>
<beans:bean id="myWebSecurityExpressionRoot" class="org.daud.common.server.security.MyWebSecurityExpressionRoot" scope="prototype"/>
<!-- For asynchronous login -->
<beans:bean id="methodSecurityAccessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<beans:property name="decisionVoters">
<beans:list>
<beans:bean class="org.springframework.security.access.vote.RoleVoter" p:rolePrefix="" />
<beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
<beans:bean class="org.daud.common.server.security.AllowPrivilegedRolesVoter">
<beans:property name="privilegedRoleTypes">
<beans:set>
<beans:value>ROOT</beans:value>
</beans:set>
</beans:property>
</beans:bean>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean class="com.gwt.ss.GwtUsernamePasswordAuthority">
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>
<beans:bean id="myAuthenticationSuccessHandler" class="org.daud.common.server.security.myAuthenticationSuccessHandler">
<!-- If redirection after logging in is to URLs containing these strings, the redirection will instead be to '/' -->
<beans:property name="partialURLsRequiringRedirection">
<beans:list>
<beans:value>/do/</beans:value>
<beans:value>/exitUser</beans:value>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="userSwitchSuccessHandler" class="org.daud.common.server.security.myUserSwitchSuccessHandler"/>
<beans:bean id="userServices" class="org.daud.common.server.security.myUserServices"/>
<beans:bean id="switchUserProcessingFilter" class="org.springframework.security.web.authentication.switchuser.SwitchUserFilter">
<beans:property name="userDetailsService" ref="userServices" />
<beans:property name="switchUserUrl" value="/admin/switchUser" />
<beans:property name="exitUserUrl" value="/admin/exitUser" />
<beans:property name="successHandler" ref="userSwitchSuccessHandler"></beans:property>
</beans:bean>
<!-- For asynchronous logout -->
<beans:bean id="logoutSuccessHandler" class="com.gwt.ss.GwtLogoutSuccessHandler" p:logoutSuccessUrl="/login" />
<beans:bean id="myAuthenticationProvider" class="org.daud.common.server.security.myAuthenticationProvider" />
<authentication-manager alias="authenticationManager">
<authentication-provider ref="myAuthenticationProvider" />
</authentication-manager>
</beans:beans>
Spring Security's web infrastructure is based entirely on standard servlet filters. It doesn't use servlets or any other servlet-based frameworks (such as Spring MVC) internally, so it has no strong links to any particular web technology.
Important Spring Security FiltersAnonymousAuthenticationFilter: when there's no authentication object in SecurityContextHolder, it creates an anonymous authentication object and put it there. FilterSecurityInterceptor: raise exceptions when access is denied. ExceptionTranslationFilter: catch Spring Security exceptions.
There are few important points to remember: Filters are executing in a specific order (Look at the number). The filters can change based on how we configure the modules. Each incoming request will go through all these filters (total 15 in our case) following a specific order.
The Spring Security filter contains a list of filter chains and dispatches a request to the first chain that matches it. The following picture shows the dispatch happening based on matching the request path ( /foo/** matches before /** ). This is very common but not the only way to match a request.
If you turn on debug logging for org.springframework.security.web.FilterChainProxy
you will see, for each request, every filter that it passes through.
For example (I am also using Spring Security OAuth).
11:18:39.123 FilterChainProxy - /user/login at position 1 of 17 in additional filter chain; firing Filter: 'BasicUserApprovalFilter' 11:18:39.123 FilterChainProxy - /user/login at position 2 of 17 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter' 11:18:39.124 FilterChainProxy - /user/login at position 3 of 17 in additional filter chain; firing Filter: 'LogoutFilter' 11:18:39.124 FilterChainProxy - /user/login at position 4 of 17 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter' 11:18:39.124 FilterChainProxy - /user/login at position 5 of 17 in additional filter chain; firing Filter: 'BasicAuthenticationFilter' 11:18:39.124 FilterChainProxy - /user/login at position 6 of 17 in additional filter chain; firing Filter: 'RequestCacheAwareFilter' 11:18:39.124 FilterChainProxy - /user/login at position 7 of 17 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter' 11:18:39.124 FilterChainProxy - /user/login at position 8 of 17 in additional filter chain; firing Filter: 'RememberMeAuthenticationFilter' 11:18:39.125 FilterChainProxy - /user/login at position 9 of 17 in additional filter chain; firing Filter: 'ForgotPasswordAuthenticationFilter' 11:18:39.125 FilterChainProxy - /user/login at position 10 of 17 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter' 11:18:39.125 FilterChainProxy - /user/login at position 11 of 17 in additional filter chain; firing Filter: 'SessionManagementFilter' 11:18:39.125 FilterChainProxy - /user/login at position 12 of 17 in additional filter chain; firing Filter: 'ExceptionTranslationFilter' 11:18:39.125 FilterChainProxy - /user/login at position 13 of 17 in additional filter chain; firing Filter: 'OAuth2ExceptionHandlerFilter' 11:18:39.125 FilterChainProxy - /user/login at position 14 of 17 in additional filter chain; firing Filter: 'VerificationCodeFilter' 11:18:39.125 FilterChainProxy - /user/login at position 15 of 17 in additional filter chain; firing Filter: 'OAuth2AuthorizationFilter' 11:18:39.125 FilterChainProxy - /user/login at position 16 of 17 in additional filter chain; firing Filter: 'OAuth2ProtectedResourceFilter' 11:18:39.125 FilterChainProxy - /user/login at position 17 of 17 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
If you want to get the filters programmatically you can inject the FilterChainProxy
and get the filterChainMap
's values.
For example:
@Autowired var filterChainProxy: FilterChainProxy = _ //... val filterChains = filterChainProxy.getFilterChainMap.values
If you only want to see the filters that <http>
adds then you should look at the source for HttpSecurityBeanDefinitionParser
.
Another thing you can do in Spring Security 3.1 is add
<sec:debug />
or
@EnableWebSecurity(debug = true)
to your application context. This adds an extra filter which will (amongs other things) report the list of security filters that will be applied to each request.
Almost complete list of Spring Security's filter types is here, although to have it all you may display all GenericFilterBean
's subclasses in SEC and read chapters 8-13 of Spring Security reference manual because, for example, you can choose one of few AbstractPreAuthenticatedProcessingFilter
implementations (and add you own by extending existing filters or GenericFilterBean
).
Example you have here uses bean configuration of FilterChainProxy
via filter-chain element and is not a default chain - you must explicitly define your own chains in order to apply filters on requests.
On the other hand you are asking about <http>
element: it has auto-config
attribute which does the following:
<http>
<form-login />
<http-basic />
<logout />
</http>
which is setting up form-login, basic authentication and logout handling services respectively.
RequestCacheAwareFilter
is called because it's probably included in filter chain of your application - your context.xml would be helpful here.
AnonymousAuthenticationFilter
(and any other filter) is added to chain if you add the bean via <sec:filter-chain>
element and configure bean with given id (usually it's class name begining with lowercased letter i.e. anonymousAuthenticationFilter
). For example:
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<constructor-arg>
<list>
<sec:filter-chain pattern="/anonym/**" filters="
anonymousAuthenticationFilter" />
<sec:filter-chain pattern="/**" filters="none" />
</list>
</constructor-arg>
</bean>
<bean id="anonymousAuthenticationFilter"
class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">
<property name="key" value="foobar"/>
<property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS"/>
</bean>
<bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager">
<property name="providers">
<list>
<ref local="anonymousAuthenticationProvider"/>
</list>
</property>
</bean>
<bean id="anonymousAuthenticationProvider"
class="org.springframework.security.authentication.AnonymousAuthenticationProvider">
<property name="key" value="foobar"/>
</bean>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With