因为security不支持JSON数据登录,就重写了UsernamePasswordAuthenticationFilter里面的attemptAuthentication方法,代码如下
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private AuthenticationBean authenticationBean = null;
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
//use jackson to deserialize json
ObjectMapper mapper = new ObjectMapper();
UsernamePasswordAuthenticationToken authRequest = null;
try (InputStream is = request.getInputStream()){
AuthenticationBean authenticationBean = mapper.readValue(is,AuthenticationBean.class);
authRequest = new UsernamePasswordAuthenticationToken(authenticationBean.getUsername(), authenticationBean.getPassword());
}catch (IOException e) {
e.printStackTrace();
authRequest = new UsernamePasswordAuthenticationToken("", "");
}finally {
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
}
}
然后在WebSecurityConfig中加入了这个过滤器。
http.addFilterAt(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
@Bean
CustomAuthenticationFilter customAuthenticationFilter() throws Exception {
CustomAuthenticationFilter filter = new CustomAuthenticationFilter();
filter.setAuthenticationSuccessHandler(authenticationSuccessHandler);
filter.setAuthenticationFailureHandler(authenticationFailureHandler);
filter.setFilterProcessesUrl("/login");
//这句很关键,重用WebSecurityConfigurerAdapter配置的AuthenticationManager,不然要自己组装AuthenticationManager
filter.setAuthenticationManager(authenticationManagerBean());
return filter;
}
此时可以用JSON传账号密码登录了,然后我又增加了记住我的相关配置。
.and().rememberMe()
.rememberMeParameter("remember_me")
.tokenRepository(persistentTokenRepository())
.tokenValiditySeconds(60).userDetailsService(userDetailsService())
@Bean
public PersistentTokenRepository persistentTokenRepository(){
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
tokenRepository.setDataSource(dataSource);
System.out.println("启动了记住我。。。");
//在第一次运行时会创建一个记住我token数据库,只能运行一次
// tokenRepository.setCreateTableOnStartup(true);
return tokenRepository;
}
发现登录成功后没有返回cookie,数据库中也没存有相应的cookie。
但是我把
http.addFilterAt(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
注释掉,用原始表单的方式登录,记住我又能正常用,前端能接收到cookie,数据库也存了cookie