Spring security 具有自定义UsernamePasswordAuthenticationFilter的Spring安全并发控制
根据新的要求,我创建了自定义UsernamePasswordAuthenticationFilter,以从登录页面捕获其他参数。正如所料,我的配置工作正常。我能够在过滤器中检索其他参数并保存到会话。但在将自定义筛选器添加到配置后,会话管理无法工作。以前,我通过将max sessions值设置为1,每个用户只允许一个会话。它现在不工作,应用程序允许同一用户多次登录。我确信只有在将自定义UsernamePasswordAuthenticationFilter集成到我的配置中之后才会发生这种情况。下面是我的spring安全配置Spring security 具有自定义UsernamePasswordAuthenticationFilter的Spring安全并发控制,spring-security,session-management,Spring Security,Session Management,根据新的要求,我创建了自定义UsernamePasswordAuthenticationFilter,以从登录页面捕获其他参数。正如所料,我的配置工作正常。我能够在过滤器中检索其他参数并保存到会话。但在将自定义筛选器添加到配置后,会话管理无法工作。以前,我通过将max sessions值设置为1,每个用户只允许一个会话。它现在不工作,应用程序允许同一用户多次登录。我确信只有在将自定义UsernamePasswordAuthenticationFilter集成到我的配置中之后才会发生这种情况。下面
http.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/login.html")
.usernameParameter("username")
.passwordParameter("password")
.and()
.logout()
.logoutSuccessUrl("/login.html")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout.html"))
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.and()
.sessionManagement()
.maximumSessions(1)
.expiredUrl("/multiplesessions.html")
.sessionRegistry(getSessionRegistry());
http.addFilterBefore(customUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
@Bean
public SessionRegistry getSessionRegistry() {
return new SessionRegistryImpl();
}
@Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(dsnyUserDetailsService);
provider.setPasswordEncoder(passwordEncoder());
auth.authenticationProvider(provider);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new StandardPasswordEncoder();
}
@Bean(name = "myAuthenticationManager")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
DsnyUsernamePasswordAuthenticationFilter customUsernamePasswordAuthenticationFilter() throws Exception {
DsnyUsernamePasswordAuthenticationFilter customUsernamePasswordAuthenticationFilter = new DsnyUsernamePasswordAuthenticationFilter();
customUsernamePasswordAuthenticationFilter.setAuthenticationManager(authenticationManagerBean());
customUsernamePasswordAuthenticationFilter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login.html", "POST"));
return customUsernamePasswordAuthenticationFilter;
}
我在这里遗漏了什么吗?我通过添加自定义ConcurrentSessionFilter解决了这个问题。这是代码,如果有人想要的话
http.sessionManagement().sessionAuthenticationStrategy(concurrentSession());
http.addFilterBefore(concurrentSessionFilter(), ConcurrentSessionFilter.class);
@Bean
public CompositeSessionAuthenticationStrategy concurrentSession() {
ConcurrentSessionControlAuthenticationStrategy concurrentAuthenticationStrategy = new ConcurrentSessionControlAuthenticationStrategy(getSessionRegistry());
concurrentAuthenticationStrategy.setMaximumSessions(1);
//concurrentAuthenticationStrategy.setExceptionIfMaximumExceeded(true);
List<SessionAuthenticationStrategy> delegateStrategies = new ArrayList<SessionAuthenticationStrategy>();
delegateStrategies.add(concurrentAuthenticationStrategy);
delegateStrategies.add(new SessionFixationProtectionStrategy());
delegateStrategies.add(new RegisterSessionAuthenticationStrategy(getSessionRegistry()));
CompositeSessionAuthenticationStrategy authenticationStrategy = new CompositeSessionAuthenticationStrategy(delegateStrategies);
return authenticationStrategy;
}
@Bean
ConcurrentSessionFilter concurrentSessionFilter() {
CustomSessionInformationExpiredStrategy redirectStrategy = new CustomSessionInformationExpiredStrategy("/pub/multiplesessions.html");
CustomConcurrentSessionFilter concurrentSessionFilter = new CustomConcurrentSessionFilter(getSessionRegistry(), redirectStrategy);
return concurrentSessionFilter;
}
CustomConcurrentSessionFilter.java,此处没有自定义代码
public class CustomConcurrentSessionFilter extends ConcurrentSessionFilter {
public CustomConcurrentSessionFilter(SessionRegistry sessionRegistry) {
super(sessionRegistry);
}
public CustomConcurrentSessionFilter(SessionRegistry sessionRegistry, SessionInformationExpiredStrategy sessionInformationExpiredStrategy) {
super(sessionRegistry, sessionInformationExpiredStrategy);
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
super.doFilter(req, res, chain);
}
}
请出示CustomSessionInformation ExpiredStrategy和CustomConcurrentSessionFilter好吗?更新了我的答案。请检查。干杯,我实际上已经解决了,但我相信它会帮助其他人!
public class CustomConcurrentSessionFilter extends ConcurrentSessionFilter {
public CustomConcurrentSessionFilter(SessionRegistry sessionRegistry) {
super(sessionRegistry);
}
public CustomConcurrentSessionFilter(SessionRegistry sessionRegistry, SessionInformationExpiredStrategy sessionInformationExpiredStrategy) {
super(sessionRegistry, sessionInformationExpiredStrategy);
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
super.doFilter(req, res, chain);
}
}