springSecurity配置
protected void configure(HttpSecurity http) throws Exception {
http.cors().and()
.authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
.and().csrf().disable()
//使用自己的filter覆盖UsernamePasswordAuthenticationFilter
.addFilterAt(usernamePasswordFilter(),UsernamePasswordAuthenticationFilter.class)
// .addFilterBefore(responseFilter(), ChannelProcessingFilter.class)
.addFilterBefore( getTokenValidateFilter(), UsernamePasswordAuthenticationFilter.class)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers("/login_url","/logout_url").permitAll()
.anyRequest().authenticated()
.and()
// .formLogin().loginPage("/login_url").loginProcessingUrl("/login_url").failureUrl("/fail_url")
// .successHandler(getLoginSuccessHandler())
// .and()
.logout().logoutUrl("/logout_url")
.logoutSuccessHandler(getLogoutSuccessHandler());
}
@Bean
public LoginSuccessHandler getLoginSuccessHandler(){
return new LoginSuccessHandler();
}
@Bean
public UsernamePasswordFilter usernamePasswordFilter() throws Exception {
UsernamePasswordFilter filter=new UsernamePasswordFilter();
filter.setAuthenticationManager(super.authenticationManager());
filter.setFilterProcessesUrl("/login_url");
filter.setAuthenticationSuccessHandler(getLoginSuccessHandler());
return filter;
}
重写UsernamePasswordAuthenticationFilter 类,让他可以判断传入的是json
public class UsernamePasswordFilter extends UsernamePasswordAuthenticationFilter {
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if(request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)){
String username=null;
String password=null;
try{
//从inputStream中读·去数据
Map<String,String > map = new ObjectMapper().readValue(request.getInputStream(), Map.class);
username =map.get("username");
password=map.get("password");
}catch (IOException e){
throw new MyDefineException(405,"传入账号密码出错");
}
if(username==null){ throw new MyDefineException(405,"用户名为空");};
if(password==null){throw new MyDefineException(405,"密码为空");}
username = username.trim();
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
this.setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
return super.attemptAuthentication(request, response);
}
}
LoginSuccessHandler类登入成功之后的处理
这里是返回token并并保存用户信息
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
Logger log = LoggerFactory.getLogger(LoginSuccessHandler.class);
//继承springSecurity的UserDetailSevice的类
@Resource
EmployeeDetailService employeeDetailService;
//用户登入之后用于保存信息的类,自定义的
@Resource
EmployeeRepository employeeRepository;
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
//从数据库根据成功的用户名查询信息
final Employee employee = (Employee) employeeDetailService.loadUserByUsername(authentication.getName());
log.info("登入保存开始");
//使用jwt工具类生成token,后面会发布一个jwt的工具类
final String token = JwtTokenUtil.generateToken(employee);
employeeRepository.insert(employee);
returnToken(httpServletResponse,token);
}
public void returnToken(HttpServletResponse response,String token) throws IOException {
//返回自定义的信息
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
Map<String,String> map=new HashMap<>();
map.put("token",token);
CommonResult<Map<String, String>> mapCommonResult = new CommonResult<>(200,"登入成功",map);
writer.write(JSON.toJSONString(mapCommonResult));
writer.flush();
}
}