- spring security过滤链filter的顺序参考, 查看org.springframework.security.config.http.HttpSecurityBeanDefinitionParser.createFilterChain代码:
//定义未排序filter集合。该集合中的对象为OrderDecorator实例。
List<OrderDecorator> unorderedFilterChain = new ArrayList<OrderDecorator>();
//添加http、认证相关的filter集合
unorderedFilterChain.addAll(httpBldr.getFilters());
unorderedFilterChain.addAll(authBldr.getFilters());
unorderedFilterChain.addAll(buildCustomFilterList(element, pc));
//根据排序规则进行排序
Collections.sort(unorderedFilterChain, new OrderComparator());
//检查每个filter与前一个filter的位置是否相同
//这里的检查主要是防止自定义filter直接配置position属性,造成与默认的filter产生order冲突
checkFilterChainOrder(unorderedFilterChain, pc, pc.extractSource(element));
// The list of filter beans
List<BeanMetadataElement> filterChain = new ManagedList<BeanMetadataElement>();
//重新定义filterChain,把经过排序的filter依次添加到filterChain集合中
for (OrderDecorator od : unorderedFilterChain) {
filterChain.add(od.bean);
}
return createSecurityFilterChainBean(element, pc, filterChain);
-
unorderedFilterChain.addAll(httpBldr.getFilters());
unorderedFilterChain.addAll(authBldr.getFilters());
unorderedFilterChain.addAll(buildCustomFilterList(element, pc));
上述代码返回的过滤链已经是经过OrderDecorator类包装的带有过滤链order顺序属性的集合。
-
Collections.sort(unorderedFilterChain, new OrderComparator());
OrderComparator就是过滤链的排序比较器了,比较算法部分代码:
public int compare(Object o1, Object o2) {
boolean p1 = (o1 instanceof PriorityOrdered);
boolean p2 = (o2 instanceof PriorityOrdered);
if (p1 && !p2) {
return -1;
}
else if (p2 && !p1) {
return 1;
}
// Direct evaluation instead of Integer.compareTo to avoid unnecessary object creation.
int i1 = getOrder(o1);
int i2 = getOrder(o2);
return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
}
检查自定义过滤链当指定position属性时有可能做成的位置冲突
-
private void checkFilterChainOrder(List<OrderDecorator> filters, ParserContext pc, Object source) {
logger.info("Checking sorted filter chain: " + filters);
for(int i=0; i < filters.size(); i++) {
OrderDecorator filter = filters.get(i);
if (i > 0) {
OrderDecorator previous = filters.get(i-1);
if (filter.getOrder() == previous.getOrder()) {
pc.getReaderContext().error("Filter beans '" + filter.bean + "' and '" +
previous.bean + "' have the same 'order' value. When using custom filters, " +
"please make sure the positions do not conflict with default filters. " +
"Alternatively you can disable the default filters by removing the corresponding " +
"child elements from <http> and avoiding the use of <http auto-config='true'>.", source);
}
}
}
}
- Spring Security用枚举类型org.springframework.security.config.http.SecurityFilters来维护filter的顺序,再用rg.springframework.security.config.http.OrderDecorator来包装filter及filter的顺序,再由org.springframework.core.OrderComparator比较filter的先后顺序。
- 要自定义Spring Security的过滤链就必须了解filter的先后顺序,否者Spring Security不会正常运作。
- 在web.xml添加spring security过滤器代理
<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.xml添加session 事件发布
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
- spring security 配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xmlns="http://www.springframework.org/schema/beans"
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">
<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
<security:filter-chain-map request-matcher="ant">
<security:filter-chain pattern="/**" filters="
securityContextPersistenceFilter,
currentSessionFilter,
asyncManagerIntegrationFilter,
logoutFilter,
usernamePasswordAuthenticationFilter,
basicAuthenticationFilter,
requestCacheAwareFilter,
contextHolderAwareRequestFilter,
rememberMeAuthenticationFilter,
anonymousAuthenticationFilter,
sessionManagementFilter,
exceptionTranslationFilter,
filterSecurityInterceptor
"/>
</security:filter-chain-map>
</bean>
<bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<constructor-arg ref="securityContextRepository"/>
<property name="forceEagerSessionCreation" value="false"/>
</bean>
<bean id="securityContextRepository"
class="org.springframework.security.web.context.HttpSessionSecurityContextRepository">
<property name="allowSessionCreation" value="true"/>
</bean>
<bean id="usernamePasswordAuthenticationFilter"
class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="customAuthenticationManager"/>
<property name="usernameParameter" value="username"/>
<property name="passwordParameter" value="password"/>
<property name="rememberMeServices" ref="enhancedPersistentTokenBasedRememberMeServices"/>
<property name="sessionAuthenticationStrategy" ref="compositeSessionAuthenticationStrategy"/>
<property name="authenticationSuccessHandler" ref="savedRequestAwareAuthenticationSuccessHandler" />
<property name="authenticationFailureHandler" ref="simpleUrlAuthenticationFailureHandler" />
<property name="requiresAuthenticationRequestMatcher" ref="filterProcessUrlRequestMatcher" />
<property name="allowSessionCreation" value="true"/>
</bean>
<bean id="savedRequestAwareAuthenticationSuccessHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler" >
<property name="requestCache" ref="httpSessionRequestCache" />
<property name="defaultTargetUrl" value="/home.html" />
</bean>
<bean id="anonymousAuthenticationFilter"
class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">
<constructor-arg value="BF93JFJ091N00Q7HF"/>
</bean>
<bean id="filterSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="customAuthenticationManager"/>
<property name="accessDecisionManager" ref="affirmativeBased"/>
<property name="securityMetadataSource">
<security:filter-security-metadata-source use-expressions="true">
<security:intercept-url pattern="/css/*" access="permitAll"/>
<security:intercept-url pattern="/js/*" access="permitAll"/>
<security:intercept-url pattern="/fonts/*" access="permitAll"/>
<security:intercept-url pattern="/signup.html*" access="permitAll"/>
<security:intercept-url pattern="/login.html*" access="permitAll"/>
<security:intercept-url pattern="/category.html*" access="permitAll"/>
<security:intercept-url pattern="/category.html*" access="permitAll"/>
<security:intercept-url pattern="/*" access="hasRole('ROLE_USER')"/>
</security:filter-security-metadata-source>
</property>
</bean>
<bean id="affirmativeBased" class="org.springframework.security.access.vote.AffirmativeBased">
<constructor-arg type="java.util.List">
<list>
<ref bean="expressionVoter"/>
<ref bean="roleVoter"/>
<ref bean="authenticatedVoter"/>
</list>
</constructor-arg>
</bean>
<bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter"/>
<bean id="authenticatedVoter" class="org.springframework.security.access.vote.AuthenticatedVoter"/>
<bean id="daoAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDao"/>
<property name="passwordEncoder" ref="passwordEncoder"/>
</bean>
<bean id="anonymousAuthenticationProvider"
class="org.springframework.security.authentication.AnonymousAuthenticationProvider">
<constructor-arg type="java.lang.String" value="BF93JFJ091N00Q7HF"/>
</bean>
<bean id="customAuthenticationManager" class="org.springframework.security.authentication.ProviderManager">
<constructor-arg type="java.util.List">
<list>
<ref bean="daoAuthenticationProvider"/>
<ref bean="anonymousAuthenticationProvider"/>
<ref bean="rememberMeAuthenticationProvider"/>
</list>
</constructor-arg>
<property name="authenticationEventPublisher" ref="defaultAuthenticationEventPublisher" />
</bean>
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg type="java.lang.String" value="/"/>
<constructor-arg>
<array>
<ref bean="logoutHandler"/>
<ref bean="enhancedPersistentTokenBasedRememberMeServices"/>
</array>
</constructor-arg>
<property name="logoutRequestMatcher" ref="logoutFilterProcessUrlRequestMatcher" />
</bean>
<bean id="rememberMeAuthenticationFilter"
class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<constructor-arg ref="customAuthenticationManager"/>
<constructor-arg ref="enhancedPersistentTokenBasedRememberMeServices"/>
</bean>
<bean id="enhancedPersistentTokenBasedRememberMeServices"
class="com.aasonwu.mycompany.EnhancedPersistentTokenBasedRememberMeServices">
<constructor-arg type="java.lang.String"
value="BoSk70Yar38~veg91DoCKs=sLaIn!metE55bURgs71rug;ILEa=Ikon79sept+ree$Fuel99baKER;wOe43JackS=TinS79babA73tiLmibs10bIsE*"/>
<constructor-arg type="org.springframework.security.core.userdetails.UserDetailsService"
ref="userDao"/>
<constructor-arg
type="org.springframework.security.web.authentication.rememberme.PersistentTokenRepository"
ref="jdbcTokenRepository"/>
<property name="cookieName" value="MYCOMPANY_REMEMBER_ME"/>
<property name="parameter" value="remember_me"/>
</bean>
<bean id="jdbcTokenRepository"
class="org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="rememberMeAuthenticationProvider"
class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
<constructor-arg
value="BoSk70Yar38~veg91DoCKs=sLaIn!metE55bURgs71rug;ILEa=Ikon79sept+ree$Fuel99baKER;wOe43JackS=TinS79babA73tiLmibs10bIsE*"/>
</bean>
<bean id="exceptionTranslationFilter" class="org.springframework.security.web.access.ExceptionTranslationFilter">
<constructor-arg ref="loginUrlAuthenticationEntryPoint"/>
<constructor-arg ref="httpSessionRequestCache"/>
<property name="accessDeniedHandler" ref="accessDeniedHandler"/>
</bean>
<bean id="loginUrlAuthenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<constructor-arg value="/login.html"/>
</bean>
<bean id="accessDeniedHandler" class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<property name="errorPage" value="/accessDenied.html"/>
</bean>
<bean id="expressionHandler"
class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/>
<bean id="expressionVoter" class="org.springframework.security.web.access.expression.WebExpressionVoter">
<property name="expressionHandler" ref="expressionHandler"/>
</bean>
<!--session manager-->
<bean id="currentSessionFilter" class="org.springframework.security.web.session.ConcurrentSessionFilter">
<constructor-arg type="org.springframework.security.core.session.SessionRegistry" ref="sessionRegistry"/>
<constructor-arg type="java.lang.String" value="/login.html"/>
<property name="logoutHandlers" ref="logoutHandler"/>
</bean>
<bean id="logoutHandler"
class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler">
<property name="invalidateHttpSession" value="true"/>
<property name="clearAuthentication" value="true"/>
</bean>
<bean id="sessionManagementFilter" class="org.springframework.security.web.session.SessionManagementFilter">
<constructor-arg ref="securityContextRepository"/>
<constructor-arg ref="compositeSessionAuthenticationStrategy"/>
<property name="authenticationFailureHandler" ref="simpleUrlAuthenticationFailureHandler"/>
<!--<property name="invalidSessionStrategy" ref="simpleRedirectInvalidSessionStrategy" />-->
</bean>
<bean id="contextHolderAwareRequestFilter"
class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter">
<property name="authenticationManager" ref="customAuthenticationManager"/>
</bean>
<bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"/>
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<bean id="sessionFixationProtectionStrategy"
class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy">
<property name="migrateSessionAttributes" value="true"/>
</bean>
<bean id="compositeSessionAuthenticationStrategy"
class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
<constructor-arg>
<list>
<ref bean="sessionControlAuthenticationStrategy"/>
<ref bean="sessionFixationProtectionStrategy"/>
<ref bean="registerSessionAuthenticationStrategy"/>
</list>
</constructor-arg>
</bean>
<bean id="sessionControlAuthenticationStrategy"
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy">
<constructor-arg ref="sessionRegistry"/>
<property name="maximumSessions" value="1"/>
<!--<property name="exceptionIfMaximumExceeded" value="false" />-->
</bean>
<bean id="registerSessionAuthenticationStrategy"
class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
<constructor-arg ref="sessionRegistry"/>
</bean>
<bean id="simpleUrlAuthenticationFailureHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<constructor-arg value="/login.html"/>
<property name="allowSessionCreation" value="true" />
</bean>
<bean id="simpleRedirectInvalidSessionStrategy"
class="org.springframework.security.web.session.SimpleRedirectInvalidSessionStrategy">
<constructor-arg value="/accessDenied.html"/>
</bean>
<bean id="asyncManagerIntegrationFilter"
class="org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter"/>
<bean id="basicAuthenticationFilter"
class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
<constructor-arg ref="customAuthenticationManager"/>
<constructor-arg ref="basicAuthenticationEntryPoint"/>
</bean>
<bean id="basicAuthenticationEntryPoint"
class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint">
<property name="realmName" value="Spring Security Application"/>
</bean>
<bean id="httpSessionRequestCache" class="org.springframework.security.web.savedrequest.HttpSessionRequestCache">
<property name="createSessionAllowed" value="true"/>
</bean>
<bean id="requestCacheAwareFilter" class="org.springframework.security.web.savedrequest.RequestCacheAwareFilter">
<constructor-arg ref="httpSessionRequestCache"/>
</bean>
<bean id="defaultAuthenticationEventPublisher" class="org.springframework.security.authentication.DefaultAuthenticationEventPublisher" />
<bean id="filterProcessUrlRequestMatcher" class="org.springframework.security.web.authentication.logout.LogoutFilter$FilterProcessUrlRequestMatcher">
<constructor-arg value="/login" />
</bean>
<bean id="logoutFilterProcessUrlRequestMatcher" class="org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter$FilterProcessUrlRequestMatcher">
<constructor-arg value="/logout"/>
</bean>
<security:global-method-security pre-post-annotations="enabled" />
</beans>
- 这个配置接近使用命名空间配置上下文的环境,并实现了自定义的userDetailServics, remember me 功能。
相关推荐
1.1. Spring Security是什么? 1.2. 历史 1.3. 发行版本号 1.4. 获得Spring Security 1.4.1. 项目模块 1.4.1.1. Core - spring-security-core.jar 1.4.1.2. Web - spring-security-web.jar 1.4.1.3. ...
1.1. Spring Security是什么? 1.2. 历史 1.3. 发行版本号 1.4. 获得Spring Security 1.4.1. 项目模块 1.4.1.1. Core - spring-security-core.jar 1.4.1.2. Web - spring-security-web.jar 1.4.1.3. Config -...
Spring Security-3.0.1 中文官方文档(翻译版) 这次发布的Spring Security-3.0.1 是一个bug fix 版,主要是对3.0 中存在的一些问题进 行修 正。文档中没有添加新功能的介绍,但是将之前拼写错误的一些类名进行...
class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"> ...
GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...
GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...
GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...
GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...
GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...
GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...
GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...
GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...
GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...
GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...
GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...
GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...
GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...
Java生成自定义控件源代码 2个目标文件 Java实现HTTP连接与浏览,Java源码下载 1个目标文件 摘要:Java源码,网络相关,HTTP Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件...
Java生成自定义控件源代码 2个目标文件 Java实现HTTP连接与浏览,Java源码下载 1个目标文件 摘要:Java源码,网络相关,HTTP Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件...