全新2.0版本极其抽象的门(Spring Security)
旧日版回顾:1.0版本
门的本质就是阻挡前往目的地的问题,再简单点门 === 问题
也就是说,只要这个东西拦住你前往目的,那他就可以赋予一个名——门!!!
第一道验证:立门 -》authorizeHttpRequests第二道验证:非法越门警告 -》exceptionHandling第三道验证:数据库用户信息 -》userDetailsService第四道验证:登录验证 -》formLogin第五道验证:退出验证 -》logout第六道验证:记住登录 -》rememberMe第七道验证:异地防御,远程登录 -》cors(跨源资源共享)第八道验证:金库保险门 -》CSRF(在未上线时,为了方便自己建议关闭,上线了记得开启!!!)构建特殊的门!!!
这是目前所用到的八道门!,配置采用lambda表达式
@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception{return http.authorizeHttpRequests(cof ->{cof.requestMatchers("/api/auth/**").permitAll();//大门可放行区cof.anyRequest().authenticated();//任何请求都要通过大门}).exceptionHandling(cof ->{cof.authenticationEntryPoint(this::onAuthenticationFailure);//暴力非法闯入警告}).userDetailsService(userService).formLogin(cof ->{cof.loginProcessingUrl("/api/auth/login");//登录验证门的位置cof.successHandler(this::onAuthenticationSuccess);//成功登录提示cof.failureHandler(this::onAuthenticationFailure);//登录失败提示}).logout(cof ->{cof.logoutUrl("/api/auth/logout");//退出登录门的位置cof.logoutSuccessHandler(this::onAuthenticationSuccess);//成功退出提示}).rememberMe(cof->{cof.rememberMeParameter("remember");//记住登录关键词cof.tokenRepository(tokenRepository());//凭证存储器cof.tokenValiditySeconds(3600 * 24 *7);//过期时间}).cors(cof ->{cof.configurationSource(configurationSource());//自定义cors}).csrf(AbstractHttpConfigurer::disable)//关闭金库大门.build();}@Beanpublic BCryptPasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();//加密}//储存登录token于数据库@Beanpublic PersistentTokenRepository tokenRepository(){JdbcTokenRepositoryImpl repository = new JdbcTokenRepositoryImpl();repository.setDataSource(dataSource);//数据源repository.setCreateTableOnStartup(false);//每次启动时自动创建数据库表单储存token(),在第一次启动时,使用true创建表单,后续使用falsereturn repository;}//自定义cors配置private CorsConfigurationSource configurationSource(){CorsConfiguration corsConfiguration = new CorsConfiguration();corsConfiguration.addAllowedOriginPattern("*");corsConfiguration.setAllowCredentials(true);corsConfiguration.addAllowedHeader("*");corsConfiguration.addAllowedMethod("*");corsConfiguration.addExposedHeader("*");UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();urlBasedCorsConfigurationSource.registerCorsConfiguration("/**",corsConfiguration);return urlBasedCorsConfigurationSource;}//成功响应头public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {response.setHeader("Content-Type", "text/plain; charset=UTF-8");//中文响应response.setCharacterEncoding("UTF-8");//请求路径如果是login,响应登陆成功if (request.getRequestURI().endsWith("/login")){response.getWriter().write(JSONObject.toJSONString(Result.success("登录成功")));//转换成json}//请求路径如果是logout,响应登录失败if (request.getRequestURI().endsWith("/logout")){response.getWriter().write(JSONObject.toJSONString(Result.success("退出登录成功")));//转换成json}}//失败响应头public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {response.setHeader("Content-Type", "text/plain; charset=UTF-8");//中文响应response.setCharacterEncoding("UTF-8");response.getWriter().write(JSONObject.toJSONString(Result.error(exception.getMessage())));//转换成json}
响应内容模板:
@Data
//json格式实体类
public class Result<T> {private Integer code;private boolean success;private T message;public Result(Integer code, boolean success, T message) {this.code = code;this.success = success;this.message = message;}public static <T> Result<T> success(){return new Result<>(0,true,null);}public static <T> Result<T> success(T data){return new Result<>(0,true,data);}public static <T> Result<T> error(T message){return new Result<>(1,false,message);}
}