package com.jiayue.ssi.config;

import com.jiayue.ssi.filter.*;
import com.jiayue.ssi.handler.*;
import com.jiayue.ssi.service.SysPolicyService;
import com.jiayue.ssi.service.SysUserService;
import com.jiayue.ssi.service.impl.UserServiceImpl;
import com.jiayue.ssi.util.JwtTokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.firewall.DefaultHttpFirewall;
import org.springframework.security.web.firewall.HttpFirewall;


/**
* WebSecurityConfig
* @author xsl
* @date 2023/2/16
*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    SysPolicyService sysPolicyService;
    @Autowired
    UserServiceImpl userServiceImpl;
    @Autowired
    CustomAuthenticationFailureHandler customAuthenticationFailureHandler;
    @Autowired
    EntryPointUnauthorizedHandler entryPointUnauthorizedHandler;
    @Autowired
    CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;
    @Autowired
    RestAccessDeniedHandler restAccessDeniedHandler;
    @Autowired
    CustomLogoutSuccessHandler customLogoutSuccessHandler;
    @Autowired
    JwtTokenUtil jwtTokenUtil;
    @Autowired
    SysUserService sysUserService;

    //    @Autowired
//    XssEscapeFilter xssEscapeFilter;
//    @Autowired
//    XssKeywordsFilter xssKeywordsFilter;
//    @Autowired
//    SqlFilter sqlFilter;
//    @Autowired
//    VerifySmFilter verifySmFilter;
    @Autowired
    InterfaceLimitFilter interfaceLimitFilter;



    @Bean
    public MyAuthenticationProvider eacpsAuthenticationProvider(){
        MyAuthenticationProvider myAuthenticationProvider = new MyAuthenticationProvider();
        myAuthenticationProvider.setUserDetailsService(userServiceImpl);
        return myAuthenticationProvider;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        // 明文+随机盐值》加密存储
        return new BCryptPasswordEncoder();
    }
    @Bean
    public HttpFirewall allowUrlEncodedSlashHttpFirewall(){
        return new DefaultHttpFirewall();
    }

//    @Override
//    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth.userDetailsService(userServiceImpl);
//    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.addFilterBefore(interfaceLimitFilter, LogoutFilter.class);
        httpSecurity.addFilterBefore(new VerifySmFilter(), LogoutFilter.class);
        httpSecurity.addFilterBefore(new XssKeywordsFilter(), LogoutFilter.class);
        httpSecurity.addFilterBefore(new XssEscapeFilter(), LogoutFilter.class);
        httpSecurity.addFilterBefore(new SqlFilter(), LogoutFilter.class);
        httpSecurity.addFilterBefore(new VerifyCodeFilter(), LogoutFilter.class);
        httpSecurity.addFilterBefore(new JwtAuthenticationTokenFilter(userServiceImpl, jwtTokenUtil, sysUserService,sysPolicyService), LogoutFilter.class);
//        httpSecurity.headers().frameOptions().disable();
//        httpSecurity.headers().httpStrictTransportSecurity().includeSubDomains(true).preload(true).maxAgeInSeconds(31536000);
        httpSecurity
                // 由于使用的是JWT，我们这里不需要csrf
                .csrf().disable()
                // 基于token，所以不需要session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().authorizeRequests()
//                .antMatchers("/user/login","/captchaImage").permitAll()
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .antMatchers("/getVerifyCode/**","/favicon.ico").permitAll()
                // 除上面外的所有请求全部需要鉴权认证
                .anyRequest().authenticated()
                .and().headers().cacheControl();
        httpSecurity.formLogin().loginProcessingUrl("/user/login")
                .successHandler(customAuthenticationSuccessHandler)
                .failureHandler(customAuthenticationFailureHandler);
        httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(customLogoutSuccessHandler);
        httpSecurity.exceptionHandling().authenticationEntryPoint(entryPointUnauthorizedHandler).accessDeniedHandler(restAccessDeniedHandler);

    }

    //针对静态资源放行
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.httpFirewall(allowUrlEncodedSlashHttpFirewall());
        /*super.configure(web);*/
        web.ignoring().antMatchers("/static/**","/assets/**","/");
    }
}
