Tuesday, 3 April 2012

Understand Spring Security 3.1 Design - Part I


Configuration in web.xml
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee">
    …
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>
            org.springframework.web.filter.DelegatingFilterProxy
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
DelegatingFilterProxy will delegate to another filter implementation which is defined as a Spring bean in the application context. It supports a “targetBeanName” filter init-param in the filter configuration, but will use the filter name as the target bean name when “targetBeanName” is not defined. In the above configuration, it looks for a Spring bean “springSecurityFilterChain” and then delegate to that bean.See API document for more information about DelegatingFilterProxy and its delegation (includes the filter lifecycle methods delegation).

Web security implementation
When the <http/> element in Spring security namespace is parsed at the first time, an instance of FilterChainProxy is created with the name “springSecurityFilterChain” (only created once). See methods in class:  oss.config.http.HttpSecurityBeanDefinitionParser
#parse(Element, ParserContext)
#registerFilterChainProxyIfNecessary(ParserContext, Object)

For each <http/> element, an instance of SecurityFilterChain is created. The <http/> element will be parsed to determine the properties of the SecurityFilterChain, including the RequestDispatcher implementation and the filters to be applied when RequestDispatcher  matches the incoming request.

FilterChainProxy then holds a list of SecurityFilterChain instances, delegate the incoming request to all the filters of matched SecurityFilterChain.

For the unsecured <http/> element (the value of security attribute is “none”), it must have either pattern attribute or request-matcher-ref attribute, and cannot define child elements like <intercept-url/>.  Also, the pattern attribute and request-matcher-ref can not be defined for the same SecurityFilterChain. See methods in class:  oss.config.http.HttpSecurityBeanDefinitionParser
#createFilterChain(Element, ParserContext)
#createSecurityFilterChain(Element, ParserContext, List<?>)

Port Mapper Creation
During the parsing of <http/> element,  a default port mapper implementation (oss.web.PortMapperImpl, with default HTTP:HTTPS pairs 80:443 and 8080:8443 ) is created and will be overridden if the <port-mappings/> element under <http/> element exists (See oss.config.http.PortMappingsBeanDefinitionParser for details). Port Mapper will be used by ChannelProcessor and RequestCache.

Authentication Manager Creation
During the parsing of <http/> element, an implementation of AuthenticationManager, that is ProviderManager, has been created. The ProviderManager can have a parent AuthenticationManager. The parent AuthenticationManager is either determined by authentication-manager-ref attribute or set by the global <authentication-manager/> element in Spring security namespace configuration. Also the ProviderManager holds a list of AuthenticationProvider which are parsed and created during Spring security filters creation:
  • AnonymousAuthenticationProvider by <anonymous/> element, also creates AnonymousAuthenticationFilter 
  • RememberMeAuthenticationProvider by <remember-me/>, also creates RememberMeAuthenticationFilter 
  • OpenIDAuthenticationProvider by <openid-login/>, also creates OpenIDAuthenticationFilter 
  • PreAuthenticatedAuthenticationProvider by <x509/>, also creates X509AuthenticationFilter 
  • PreAuthenticatedAuthenticationProvider by <jee/>, also creates J2eePreAuthenticatedProcessingFilter
The instance of the AuthenticationManager will then be used by a set of Spring filters and shared within the current SecurityFilterChain (i.e, current <http/> element).
  •  <remember-me/> 
  • <http-basic/> 
  • <form-login/> 
  • <openid-login/> 
  • <x509/> 
  • <jee/> 
  • <intercept-url/>
The ProviderManager delegates its authentication request to its AuthenticationProvider list or to its parent if no AuthenticationProvider can accomplish the request and the parent exists.

See oss.config.authentication.AuthenticationManagerBeanDefinitionParser and oss.config.authentication.AuthenticationProviderBeanDefinitionParser for the global <authentication-manager/> and its nested <authentication-provider/> element configuration. An <authentication-provider/> namespace element will create an instance of DaoAuthenticationProvider.

No comments:

Post a Comment