spring security设置(springSecurityFilterChain与DelegatingFilterProxy)

20 篇文章 0 订阅
 

下面是从外网找到的一篇好文章,好文采!但是,有一点想不明白的是,这么好的文章为什么就要把人家挡在国门之外!想不通……

Simple web application with Spring Security: Part 13

In the last few pages on spring security series, I was about to tackle method-level security and domain-instance security using spring security; But before doing this, I am going to go back to basics and explore the basics of spring security in a deeper way.

Back to basics

We are going to revert to simplest configuration first of all:

In our springsecuritywebapp-servlet.xml file, we remove the configuration for the aclDemoController for now and any reference to it within the file.

In our web.xml:

We configure a listener to load the context of the web application at start up. This will load our applicationContext-security.xml file.

We register a filter named springSecurityFilterChain that delegates all requests matching the url pattern ‘/*’ to a DelegatingFilterProxy.

<!--
- Location of the XML file that defines the root application context -
Applied by ContextLoaderListener.
-->
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>
		    WEB-INF\applicationContext-security.xml
        </param-value>
</context-param>

<!--
- Loads the root application context of this web app at startup. - The
application context is then available via -
WebApplicationContextUtils.getWebApplicationContext(servletContext).
-->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

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

In our applicationContext-security.xml we leave it empty like so:

<?xml version="1.0" encoding="UTF-8"?>
<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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">

</beans:beans>
Build and deploy

The application builds ok and deploys to tomcat. However it fails when starting up on tomcat due to:

SEVERE: Error filterStart
SEVERE: Context [/springsecuritywebapp] startup failed due to previous errors

Looking in the tomcat logs we see the following error:

23/12/2008 18:33:28 org.apache.catalina.core.StandardContext filterStart
SEVERE: Exception starting filter springSecurityFilterChain
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'springSecurityFilterChain' is defined
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:387)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:971)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:246)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:168)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:884)
	at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:216)
	at org.springframework.web.filter.DelegatingFilterProxy.initFilterBean(DelegatingFilterProxy.java:145)
	at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:179)

Clearly the problem is that we haven’t configured any bean named ‘springSecurityFilterChain’.

Fixing springSecurityFilterChain problem

If we use the <http> configuration element it should auto create a default springSecurityFilterChain.

We update our applicationContext-security.xml to look like so:

<http auto-config="false" session-fixation-protection="none">
</http>

When we build and deploy this we get another problem:

org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: No AuthenticationEntryPoint could be established. Please make sure you have a login mechanism configured through the namespace (such as form-login) or specify a custom AuthenticationEntryPoint with the custom-entry-point-ref attribute
Offending resource: ServletContext resource [/WEB-INF/applicationContext-security.xml]
	at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68)
	at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85)
	at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:72)

So spring security is failing fast as it expects us to have some form of authentication mechanism:

We update our applicationContext-security.xml to look like so:

<http auto-config="false" session-fixation-protection="none">
    <form-login login-page="/login.jsp" default-target-url="/home.htm" />
</http>

Building and deploy, we see another problem reported on tomcat:

org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name '_authenticationManager': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: No authentication providers were found in the application context

So spring security expects an authentication provider to be configured to facilitate the form login via an AuthenticationManager that is being automatically created by spring security and named _authenticationManager.

So we update our applicationContext-security.xml again to add the following snippet:

<authentication-provider>
   <user-service id="userDetailsService">
      <user password="password" name="username" authorities="ROLE_USER" />
   </user-service>
</authentication-provider>

Building and deploying again, we see from the tomcat logs that the application has started successfully. The authentication through form login (which is all we have configured) works as it should.

How it works behind the scenes

When the applications starts correctly using the configuration laid out as above, see see from the tomcat logs the following details:

INFO: Pre-instantiating singletons in
org.springframework.beans.factory.support.DefaultListableBeanFactory@195afdb: defining beans
[
_authenticationManager,
_filterChainProxy,
_httpSessionContextIntegrationFilter,
_filterChainProxyPostProcessor,
_filterChainList,
_securityContextHolderAwareRequestFilter,
_accessManager,
_portMapper,
_exceptionTranslationFilter,
_filterSecurityInterceptor,
_formLoginFilter,
_formLoginEntryPoint,
_entryPointInjectionBeanPostProcessor,
_userServiceInjectionPostProcessor,
org.springframework.security.providers.dao.DaoAuthenticationProvider#0,
userDetailsService,
org.springframework.security.config.AuthenticationProviderBeanDefinitionParser$AuthenticationProviderCacheResolver#0
]; root of factory hierarchy

What is happening is that from that small amount of configuration, spring security is instantiating a number of beans to enable the functionality. Of special interest is the _filterChainProxy. From the logs, we see the FilterChainProxy is configured as:

INFO: FilterChainProxy: FilterChainProxy[
UrlMatcher = org.springframework.security.util.AntUrlPathMatcher[requiresLowerCase='true']; Filter Chains: {/**=[
org.springframework.security.context.HttpSessionContextIntegrationFilter[ order=200; ],
org.springframework.security.ui.webapp.AuthenticationProcessingFilter[ order=700; ],
org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter[ order=1100; ],
org.springframework.security.ui.ExceptionTranslationFilter[ order=1400; ],
org.springframework.security.intercept.web.FilterSecurityInterceptor@1cd6a32]
}]

Following a HTTP Request

As an example, I try to visit the following page on the application: http://localhost:8080/springsecuritywebapp/login.jsp. This requests starts off its journey navigating through the apache tomcat container:

http-request-stack-trace-tomcat-springsecurity

Apache tomcats ApplicationFilterChain.doInternalChain method retrieves filter configured in our web.xml.

ApplicationFilterConfig[name=springSecurityFilterChain, filterClass=org.springframework.web.filter.DelegatingFilterProxy]

It then uses the filter [ of type DelegatingFilterProxy] and invokes doFilter on this passing the request and response types. As the DelegatingFilterProxy’s javadoc states:

This approach is particularly useful for Filter implementation with complex setup needs, allowing to apply the full Spring bean definition machinery to Filter instances. Alternatively, consider standard Filter setup in combination with looking up service beans from the Spring root application context.

And this is its purpose here, to delegate to a FilterChainProxy for which a bean is already instantiated (_filterChainProxy). This is then responsible for filtering the request through each of filters that are part of its VirtualFilterChain.

From our initial configuration set up for spring security, we have have five filters that are part of FilterChainProxys VirtualFilterChain. These are in order of execution:

  1. HttpSessionContextIntegrationFilter
  2. AuthenticationProcessingFilter
  3. SecurityContextHolderAwareRequestFilter
  4. ExceptionTranslationFilter
  5. FilterSecurityInterceptor

In the next part I will talk about what happens to our request to reach http://localhost:8080/springsecuritywebapp/login.jsp in each of these filters.

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值