import com.fasterxml.jackson.databind.ObjectMapper; import com.javaboy.vms.entity.VUser; import com.javaboy.vms.service.impl.VUserServiceImpl; import com.javaboy.vms.util.ResultDTO; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.*; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; import javax.annotation.Resource; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * Spring Security 配置类 * @author: gy * @date: 2021-04-15 16:35 */ @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Resource private VUserServiceImpl vUserService; @Bean PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(vUserService); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .loginProcessingUrl("/doLogin") .usernameParameter("username") .passwordParameter("password") // 登录成功回调 .successHandler(new AuthenticationSuccessHandler() { @Override public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException { resp.setContentType("application/json;charset=utf-8"); PrintWriter out = resp.getWriter(); VUser vUser = (VUser) authentication.getPrincipal(); vUser.setPassword(null); ResultDTO resultDTO = ResultDTO.success("登录成功", vUser); String s = new ObjectMapper().writeValueAsString(resultDTO); out.write(s); out.flush(); out.close(); } }) // 登录失败回调 .failureHandler(new AuthenticationFailureHandler() { @Override public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException exception) throws IOException, ServletException { resp.setContentType("application/json;charset=utf-8"); PrintWriter out = resp.getWriter(); ResultDTO resultDTO = ResultDTO.error("登录失败"); if (exception instanceof LockedException) { resultDTO.setMsg("账户被锁定,请联系管理员!"); } else if (exception instanceof CredentialsExpiredException) { resultDTO.setMsg("密码过期,请联系管理员!"); } else if (exception instanceof AccountExpiredException) { resultDTO.setMsg("账户过期,请联系管理员!"); } else if (exception instanceof DisabledException) { resultDTO.setMsg("账户被禁用,请联系管理员!"); } else if (exception instanceof BadCredentialsException) { resultDTO.setMsg("用户名或者密码输入错误,请重新输入!"); } out.write(new ObjectMapper().writeValueAsString(resultDTO)); out.flush(); out.close(); } }) .permitAll() .and() .logout() // 登出回调 .logoutSuccessHandler(new LogoutSuccessHandler() { @Override public void onLogoutSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException { resp.setContentType("application/json;charset=utf-8"); PrintWriter out = resp.getWriter(); out.write(new ObjectMapper().writeValueAsString(ResultDTO.success("注销成功!"))); out.flush(); out.close(); } }) .permitAll() .and() .csrf().disable() // 没有认证时,在这里处理结果,不要重定向 .exceptionHandling().authenticationEntryPoint(new AuthenticationEntryPoint() { @Override public void commence(HttpServletRequest req, HttpServletResponse resp, AuthenticationException e) throws IOException, ServletException { resp.setContentType("application/json;charset=utf-8"); PrintWriter out = resp.getWriter(); ResultDTO resultDTO = ResultDTO.error("访问失败"); if (e instanceof InsufficientAuthenticationException) { resultDTO.setMsg("请求失败,请联系管理员!"); } out.write(new ObjectMapper().writeValueAsString(resultDTO)); out.flush(); out.close(); } }); } }