我已经使用Spring Security和Persistent RememberMe功能成功配置了Spring应用程序。但是,以下步骤在Safari 7.1.2中产生错误:
产生的错误是:
org.springframework.security.web.authentication.rememberme.CookieTheftException:无效的记住我令牌(系列/令牌)不匹配。意味着之前的cookie盗窃攻击。
在FireFox 31.3.0中执行这些完全相同的步骤,可以按预期再次成功登录用户。
以下是应用程序安全性的Java配置:
@Configuration
@EnableWebMvcSecurity
@ComponentScan(basePackages={"com.example.app.config"})
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
private DataSource dataSource;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/new").access("hasRole('USER')")
.antMatchers("/call/**").access("hasRole('USER')")
.antMatchers("/contacts/**").access("hasRole('USER')")
.antMatchers("/").access("hasRole('USER')")
.antMatchers("/resources/css/**").permitAll()
.antMatchers("/resources/js/**").permitAll()
.and()
.formLogin()
.loginPage("/signin")
.loginProcessingUrl("/j_spring_security_check")
.usernameParameter("username")
.passwordParameter("password")
.permitAll();
http.rememberMe()
.key("notasecret")
.rememberMeServices(rememberMeServices())
.userDetailsService(userDetailsService());
}
@Bean
public JdbcDaoImpl userDetailsService() {
JdbcDaoImpl userDetailsService = new JdbcDaoImpl();
userDetailsService.setDataSource(dataSource);
return userDetailsService;
}
@Bean
public PersistentTokenBasedRememberMeServices rememberMeServices() {
PersistentTokenBasedRememberMeServices services = new PersistentTokenBasedRememberMeServices("notasecret", userDetailsService(), tokenRepository());
services.setTokenValiditySeconds(43200);
return services;
}
@Bean
public JdbcTokenRepositoryImpl tokenRepository() {
JdbcTokenRepositoryImpl repository = new JdbcTokenRepositoryImpl();
repository.setDataSource(dataSource);
return repository;
}
以下是Safari的调试跟踪中发生的情况:
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
DEBUG: org.springframework.security.web.context.HttpSessionSecurityContextRepository - No HttpSession currently exists
DEBUG: org.springframework.security.web.context.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: null. A new one will be created.
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
DEBUG: org.springframework.security.web.header.writers.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@69d3d174
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
DEBUG: org.springframework.security.web.util.matcher.AntPathRequestMatcher - Request 'GET /' doesn't match 'POST /logout
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 6 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
DEBUG: org.springframework.security.web.util.matcher.AntPathRequestMatcher - Request 'GET /' doesn't match 'POST /j_spring_security_check
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 7 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 8 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - / at position 9 of 13 in additional filter chain; firing Filter: 'RememberMeAuthenticationFilter'
DEBUG: org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices - Remember-me cookie detected
DEBUG: org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices - Cancelling cookie
DEBUG: org.springframework.security.web.context.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
DEBUG: org.springframework.security.web.context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
Jan 27, 2015 11:54:17 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/ocl] threw exception
org.springframework.security.web.authentication.rememberme.CookieTheftException: Invalid remember-me token (Series/token) mismatch. Implies previous cookie theft attack.
我的理论是日志中的重点是说明"取消cookie"是问题。但是,我不知道为什么会这样。
如果有人遇到此问题,或者上述配置出现问题或遗漏,请与我们联系。
答案 0 :(得分:0)
我从一个简单的安全专用应用程序开始,以消除所有其他复杂性,并能够让我记住我的功能。我在我的测试应用程序和主应用程序之间的相应POM.xml文件中取得了一个高峰,并从应用程序中删除了以下依赖项,其中记住我无法正常工作:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.2.5.RELEASE</version>
</dependency>
这一定与spring-security-core
冲突,因为删除依赖项后一切正常。