content: package com.kefu.admin.common.config;
  
  import com.kefu.admin.common.jwt.JwtAuthenticationEntryPoint;
  import com.kefu.admin.common.jwt.JwtAuthenticationTokenFilter;
  import com.kefu.admin.common.jwt.JwtUserServiceImpl;
  
  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.authentication.AuthenticationManager;
  import org.springframework.security.config.BeanIds;
  import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  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.configuration.EnableWebSecurity;
  import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
  import org.springframework.security.config.http.SessionCreationPolicy;
  import org.springframework.security.core.userdetails.UserDetailsService;
  import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  import org.springframework.security.crypto.password.PasswordEncoder;
  import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
  import org.springframework.web.cors.CorsUtils;
  
  /**
   * Srping Security配置
   *
   * @author feng
   * @date 2019-05-20
   */
  @Configuration
  @EnableWebSecurity
  @EnableGlobalMethodSecurity(prePostEnabled = true)
  public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  
      @Autowired
      private JwtUserServiceImpl userDetailsService;
  
      @Autowired
      private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
  
      @Autowired
      private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
  
      /**
       * 这里记住一定要重新父类的对象，不然在注入 AuthenticationManager时会找不到，默认spring security 没有给我们注入到容器中
       *
       * @return
       * @throws Exception
       */
      @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
      @Override
      public AuthenticationManager authenticationManagerBean() throws Exception {
          return super.authenticationManagerBean();
      }
  
      /**
       * 用户登录密码加密
       *
       * @return
       */
      @Bean
      public PasswordEncoder passwordEncoder() {
          return new BCryptPasswordEncoder();
      }
  
      @Override
      protected void configure(AuthenticationManagerBuilder auth) throws Exception {
          auth.userDetailsService(userDetailsService)
                  .passwordEncoder(passwordEncoder());
      }
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http.cors().and().csrf().disable()
                  // 未授权处理
                  .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
                  .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                  .and().authorizeRequests()
                  .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                  .antMatchers("/auth/**",
                          "/actuator/**",
                          "/common/**",
                          "/images/**",
                          "/v2/api-docs",
                          "/doc.html",
                          "/configuration/ui",
                          "/swagger-resources",
                          "/configuration/security",
                          "/swagger-ui.html",
                          "/webjars/**",
                          "/swagger-resources/configuration/ui",
                          "/swagge‌​r-ui.html").permitAll()
                  .anyRequest().authenticated()
                  .and().headers().cacheControl();
  
          // 注入jwt过滤器
          http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
  
          ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http.authorizeRequests();
          // 让Spring security放行所有preflight request
          registry.requestMatchers(CorsUtils::isPreFlightRequest).permitAll();
      }
  }
  