java定制Spring过滤器导致链中的下一个过滤器不启动?
我使用的是一个定制的Spring安全过滤器,它覆盖AbstractAuthenticationProcessingFilter,但我一定写错了,因为它似乎从未调用过滤器链的其余部分。具体来说,我依靠OpenEntityManagerInViewFilter过滤器来确保Jackson+Hibernate可以处理延迟加载的对象
如果我的网站。xml有OpenEntityManagerViewFilter首先,一切正常:
<filter>
<filter-name>hibernateFilterChain</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hibernateFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<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>
但是,如果我将springSecurityFilterChain放在顶部,我的应用程序的行为就好像我根本没有指定OpenEntityManagerViewFilter一样
这是我的安全措施。xml:
<?xml version="1.0"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<security:http entry-point-ref="restAuthenticationEntryPoint"
use-expressions="true" create-session="stateless">
<security:custom-filter ref="authenticationTokenProcessingFilter"
position="FORM_LOGIN_FILTER" />
<security:intercept-url pattern="/**"
access="isAuthenticated()" />
<security:logout />
</security:http>
<bean class="edu.ucdavis.dss.dw.security.CustomTokenAuthenticationFilter"
id="authenticationTokenProcessingFilter">
<constructor-arg type="java.lang.String">
<value>/**</value>
</constructor-arg>
</bean>
<security:authentication-manager>
<security:authentication-provider
user-service-ref="userService"></security:authentication-provider>
</security:authentication-manager>
<bean id="userService" class="edu.ucdavis.dss.dw.services.UserAuthenticationService"></bean>
</beans>
最后,这里是CustomTokenAuthenticationFilter本身,这可能会导致问题:
public class CustomTokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
@Autowired @Qualifier("org.springframework.security.authenticationManager")
private AuthenticationManager authenticationManager;
public CustomTokenAuthenticationFilter(String defaultFilterProcessesUrl) {
super(defaultFilterProcessesUrl);
super.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher(defaultFilterProcessesUrl));
setAuthenticationManager(new NoOpAuthenticationManager());
setAuthenticationSuccessHandler(new TokenSimpleUrlAuthenticationSuccessHandler());
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
String token = request.getParameter("token");
if(token == null) {
throw new AuthenticationServiceException("Token Missing");
}
Authentication authResponse;
try {
authResponse = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(token, "dssit"));
} catch (AuthenticationException e) {
throw new AuthenticationServiceException("Bad Token");
}
return authResponse;
}
}
总结:我做了一个自定义的安全过滤器,它似乎没有调用后面列出的任何过滤器。如果我删除我的自定义过滤器并使用一些内置的东西,比如安全性:http basic,它就可以正常工作
提前感谢您提供的任何帮助
# 1 楼答案
据我所知,Spring身份验证过滤器旨在对请求进行身份验证,然后重定向到某个地方,启动一个全新的请求。这意味着过滤器链被故意停止。其思想是,一旦经过身份验证,并且在新请求中,身份验证会话将已经存在,这样身份验证过滤器就不必再次重定向。至少,这是我从一点调试中得到的理解
为了避免这种行为,您必须实现自己的AbstractAuthenticationProcessingFilter、AuthenticationEntryPoint、AbstractAuthenticationToken、AuthenticationProvider和SimpleRuthenticationSuccessHandler
# 2 楼答案
AbstractAuthenticationProcessingFilter
类具有以下可重写的方法:在使用筛选器启动身份验证之前调用此方法(在
doFilter
):子类应该重写这个方法,以检查它是否可以对请求进行身份验证:如果令牌不存在或无效,它应该返回false
例如:
# 3 楼答案
是否要尝试添加
到CustomTokenAuthenticationFilter类