导包(略……)
/** * @author Chase Meng * @description: 自定义登录逻辑(访问数据库) * @created on 2020/9/7 */ @Configuration public class CustomizeUserDetailsService implements UserDetailsService { @Autowired private LoginOperate loginOperate; @Autowired private PasswordEncoder passwordEncoder; // @Autowired // private Encryption encryption; // @Bean // public PasswordEncoder passwordEncoder() { // return new BCryptPasswordEncoder(); // } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { Admin admin =loginOperate.findUserByUsername(username); if(username==null||username.equals("")){ throw new RuntimeException("用户名不能为空!"); } if(admin==null){ throw new RuntimeException("用户名不存在!"); } List<GrantedAuthority> authorities=new ArrayList<GrantedAuthority>(); authorities.add(new SimpleGrantedAuthority("ROLE_"+"normal")); //由于没有设置授权,所以随便给一个身份normal User userDetails = new User(admin.getUsername(), passwordEncoder.encode(admin.getPassword()), authorities); return userDetails; } }
** * @author Chase Meng * @description: 自定义登录失败处理器 * @created on 2020/9/7 */ @Component public class CustomizeAuthenctiationFailureHandler extends SimpleUrlAuthenticationFailureHandler { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { //super.onAuthenticationFailure(request, response, exception); Result result=new Result(); if(exception instanceof BadCredentialsException){ //密码错误 result.setCode(1200); result.setMsg("密码错误!"); }else if(exception instanceof InternalAuthenticationServiceException){ //用户不存在 result.setCode(1100); result.setMsg("不存在该用户!"); } else if(exception instanceof AccountExpiredException){ //账号过期 } else if(exception instanceof CredentialsExpiredException){ //密码过期 }else if(exception instanceof DisabledException){ //帐号不可用 }else if(exception instanceof LockedException){ //帐号锁定 }else{ //其他错误 } result.setState(false); // 把result对象转成 json 格式 字符串 通过 response 以application/json;charset=UTF-8 格式写到响应里面去 response.setContentType("application/json; charset=utf-8"); PrintWriter out = response.getWriter(); out.write(result.toJsonWhenDataIsNull()); } } /** * 或者使用实现AuthenticationFailureHandler类的方法来定义 */ //@Component //public class CustomizeAuthenctiationFailureHandler implements AuthenticationFailureHandler { // @Override // public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { // //super.onAuthenticationFailure(request, response, exception); // System.out.println("fauilt"); // Result result=new Result(); // response.setContentType("application/json; charset=utf-8"); // result.setCode(1000); // result.setMsg("登录失败!"); // result.setState(false); // // 把result对象转成 json 格式 字符串 通过 response 以application/json;charset=UTF-8 格式写到响应里面去 // response.setContentType("application/json; charset=utf-8"); // PrintWriter out = response.getWriter(); // out.write(result.toJsonWhenDataIsNull()); // } //}
/** * @author Chase Meng * @description: 自定义登录成功处理器 * @created on 2020/9/7 */ @Component public class CustomizeAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { @Autowired private ObjectMapper objectMapper; @Override public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { Result result = new Result(); result.setCode(2000); result.setMsg("登录成功!"); result.setState(true); Admin admin=new Admin(); result.setData("{\"username\" : \""+SecurityContextHolder.getContext().getAuthentication().getName()+"\"}");//响应数据携带用户名 // 把result对象转成 json 格式 字符串 通过 response 以application/json;charset=UTF-8 格式写到响应里面去 httpServletResponse.setContentType("application/json; charset=utf-8"); PrintWriter out = httpServletResponse.getWriter(); out.write(result.toJsonWhenDataIsNull()); } } /** * 或者使用实现AuthenticationSuccessHandler类的方法来定义 */ /*@Component public class CustomizeAuthenticationSuccessHandler implements AuthenticationSuccessHandler { @Override public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { Result result = new Result(); result.setCode(2000); result.setMsg("登录成功!"); result.setState(true); Admin admin=new Admin(); result.setData("{\"username\" : \""+SecurityContextHolder.getContext().getAuthentication().getName()+"\"}");//响应数据携带用户名 // 把result对象转成 json 格式 字符串 通过 response 以application/json;charset=UTF-8 格式写到响应里面去 httpServletResponse.setContentType("application/json; charset=utf-8"); PrintWriter out = httpServletResponse.getWriter(); out.write(result.toJsonWhenDataIsNull()); } }*/
/** * @author Chase Meng * @description: 屏蔽重定向的登录页面,并返回统一的json格式的数据 * @created on 2020/9/7 */ @Component public class CustomizeAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException { Result result=new Result(); httpServletResponse.setContentType("application/json; charset=utf-8"); result.setCode(1000); result.setMsg("没有登录权限,请先登录!"); result.setState(false); PrintWriter out = httpServletResponse.getWriter(); out.write(result.toJsonWhenDataIsNull()); } }
/** * @author Chase Meng * @description: 自定义注销成功处理器 * @created on 2020/9/7 */ @Component public class CustomizeLogoutSuccessHandler implements LogoutSuccessHandler { @Override public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { Result result=new Result(); httpServletResponse.setContentType("application/json; charset=utf-8"); result.setCode(1000); result.setMsg("注销成功!"); result.setState(true); PrintWriter out = httpServletResponse.getWriter(); out.write(result.toJsonWhenDataIsNull()); httpServletResponse.getWriter().flush(); } }
/** * @author Chase Meng * @Description 自定义spring security配置 * @Date Create in 2020/09/07 */ @EnableWebSecurity public class MySecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired private CustomizeAuthenticationSuccessHandler myAuthenticationSuccessHandler; @Autowired private CustomizeAuthenctiationFailureHandler myAuthenctiationFailureHandler; @Autowired private CustomizeAuthenticationEntryPoint myAuthenticationEntryPoint; @Autowired private CustomizeLogoutSuccessHandler logoutSuccessHandler; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity http) throws Exception { //配置拦截规则 //按先后注册的先后顺序匹配,因此顺序要格外注意 http.authorizeRequests() .antMatchers("/upload/picture").permitAll() //放行图片上传接口 .antMatchers("/*d/**").authenticated() //拦截所有对回收站的查询 .antMatchers(HttpMethod.GET).permitAll() //放行其他所有GET请求 .anyRequest().authenticated() //拦截其余请求 .and() .csrf().disable(); // 禁用跨站攻击,否则允许通行的其他路径的除了get请求之外的都会被拦截(包括登录注销接口) //开启跨域 http.cors(); //开启自动配置登录 http.formLogin().permitAll() .successHandler(myAuthenticationSuccessHandler) //注册自定义处理器 .failureHandler(myAuthenctiationFailureHandler) // .loginPage("http://localhost:8080/") //登录页(GET) .loginProcessingUrl("/user/login"); //登录接口(POST) //记住密码 // http.rememberMe(); //屏蔽Spring Security默认重定向登录页面以实现前后端分离功能 http.exceptionHandling() .authenticationEntryPoint(myAuthenticationEntryPoint);//匿名用户访问无权限资源时的异常 // .accessDeniedHandler(); //用来解决认证过的用户访问无权限资源时的异常 http.logout().permitAll() .logoutSuccessHandler(logoutSuccessHandler) //注册登录失败处理器 .deleteCookies("JSESSIONID") //登出后删除cookie .logoutUrl("/user/logout"); //登出接口(POST) } }
数据库中只有一个管理员:
username:admin
password:abc123
[Spring Security] 前后端分离项目中的后端代码简单示例
原文:https://www.cnblogs.com/chasemeng/p/13631055.html