class SecurityConfigurer {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private AuthIgnoreConfig authIgnoreConfig;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {<FILL_FUNCTION_BODY>}

    // 解决跨域
    public CorsConfigurationSource corsConfigurationSource() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", corsConfiguration);
        return source;
    }

    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        // 开放静态资源权限
        return web -> web.ignoring().antMatchers("/actuator/**", "/css/**", "/error");
    }

    @Bean
    public CustomDaoAuthenticationProvider authenticationProvider() {
        CustomDaoAuthenticationProvider authenticationProvider = new CustomDaoAuthenticationProvider();
        authenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
        authenticationProvider.setUserDetailsService(userDetailsService());
        return authenticationProvider;
    }

    @Bean
    public AuthenticationManager authenticationManager() {
        return new ProviderManager(Arrays.asList(authenticationProvider()));
    }

    @Bean
    public AuthenticationFailureHandler authenticationFailureHandler() {
        return new CustomAuthenticationFailHandler();
    }

    @Bean
    public LogoutHandler logoutHandler() {
        return new CustomLogoutSuccessHandler();
    }

    @Bean
    public AuthenticationSuccessHandler authenticationSuccessHandler() {
        return new CustomAuthenticationSuccessHandler();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return new CustomUserDetailsService();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

        List<String> permitAll = authIgnoreConfig.getIgnoreUrls();
        permitAll.add("/error");
        permitAll.add("/v3/**");
        permitAll.add("/swagger-ui/**");
        permitAll.add("/swagger-resources/**");
        permitAll.add(Constant.TOKEN_ENTRY_POINT_URL);
        permitAll.add(Constant.TOKEN_LOGOUT_URL);
        String[] urls = permitAll.stream().distinct().toArray(String[]::new);

        // 基于 token，不需要 csrf
        http.csrf().disable().authorizeRequests().antMatchers(HttpMethod.OPTIONS,"/**").permitAll();
        // 跨域配置
        http.cors().configurationSource(corsConfigurationSource());

        // 基于 token，不需要 session
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        // 权限
        http.authorizeRequests(authorize ->
                // 开放权限
                authorize.antMatchers(urls).permitAll()
                // 其他地址的访问均需验证权限
                .anyRequest().authenticated());
        // 设置登录URL
        http.formLogin()
                .loginProcessingUrl(Constant.TOKEN_ENTRY_POINT_URL)
                .successHandler(authenticationSuccessHandler())
                .failureHandler(authenticationFailureHandler());
        // 设置退出URL
        http.logout()
                .logoutUrl(Constant.TOKEN_LOGOUT_URL)
                .logoutSuccessUrl("/sys/logout")
                .addLogoutHandler(logoutHandler());
        // 如果不用验证码，注释这个过滤器即可
        http.addFilterBefore(new ValidateCodeFilter(redisTemplate, authenticationFailureHandler()), UsernamePasswordAuthenticationFilter.class);
        // token 验证过滤器
        http.addFilterBefore(new AuthenticationTokenFilter(authenticationManager(), authIgnoreConfig,redisTemplate), UsernamePasswordAuthenticationFilter.class);
        // 认证异常处理
        http.exceptionHandling().authenticationEntryPoint(new TokenAuthenticationFailHandler());
        // 用户管理service
        http.userDetailsService(userDetailsService());
        return http.build();
    
<no_super_class>