| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 | package com.genersoft.iot.vmp.conf.security;import com.genersoft.iot.vmp.conf.UserSetting;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.annotation.Order;import org.springframework.security.authentication.AuthenticationManager;import org.springframework.security.authentication.dao.DaoAuthenticationProvider;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.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.web.authentication.UsernamePasswordAuthenticationFilter;import org.springframework.web.cors.CorsConfiguration;import org.springframework.web.cors.CorsConfigurationSource;import org.springframework.web.cors.CorsUtils;import org.springframework.web.cors.UrlBasedCorsConfigurationSource;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;/** * 配置Spring Security * * @author lin */@Configuration@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled = true)@Order(1)public class WebSecurityConfig extends WebSecurityConfigurerAdapter {    private final static Logger logger = LoggerFactory.getLogger(WebSecurityConfig.class);    @Autowired    private UserSetting userSetting;    @Autowired    private DefaultUserDetailsServiceImpl userDetailsService;    /**     * 登出成功的处理     */    @Autowired    private LogoutHandler logoutHandler;    /**     * 未登录的处理     */    @Autowired    private AnonymousAuthenticationEntryPoint anonymousAuthenticationEntryPoint;    @Autowired    private JwtAuthenticationFilter jwtAuthenticationFilter;    /**     * 描述: 静态资源放行,这里的放行,是不走 Spring Security 过滤器链     **/    @Override    public void configure(WebSecurity web) {        if (userSetting.isInterfaceAuthentication()) {            ArrayList<String> matchers = new ArrayList<>();            matchers.add("/");            matchers.add("/#/**");            matchers.add("/static/**");            matchers.add("/swagger-ui.html");            matchers.add("/swagger-ui/");            matchers.add("/index.html");            matchers.add("/doc.html");            matchers.add("/webjars/**");            matchers.add("/swagger-resources/**");            matchers.add("/v3/api-docs/**");            matchers.add("/js/**");            matchers.add("/api/device/query/snap/**");            matchers.add("/record_proxy/*/**");            matchers.add("/api/emit");            matchers.add("/favicon.ico");            // 可以直接访问的静态数据            web.ignoring().antMatchers(matchers.toArray(new String[0]));        }    }    /**     * 配置认证方式     *     * @param auth     * @throws Exception     */    @Override    protected void configure(AuthenticationManagerBuilder auth) throws Exception {        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();        // 设置不隐藏 未找到用户异常        provider.setHideUserNotFoundExceptions(true);        // 用户认证service - 查询数据库的逻辑        provider.setUserDetailsService(userDetailsService);        // 设置密码加密算法        provider.setPasswordEncoder(passwordEncoder());        auth.authenticationProvider(provider);    }    @Override    protected void configure(HttpSecurity http) throws Exception {        http.headers().contentTypeOptions().disable()                .and().cors().configurationSource(configurationSource())                .and().csrf().disable()                .sessionManagement()                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)                // 配置拦截规则                .and()                .authorizeRequests()                .requestMatchers(CorsUtils::isPreFlightRequest).permitAll()                .antMatchers(userSetting.getInterfaceAuthenticationExcludes().toArray(new String[0])).permitAll()                .antMatchers("/api/user/login", "/index/hook/**", "/swagger-ui/**", "/doc.html").permitAll()                .anyRequest().authenticated()                // 异常处理器                .and()                .exceptionHandling()                .authenticationEntryPoint(anonymousAuthenticationEntryPoint)                .and().logout().logoutUrl("/api/user/logout").permitAll()                .logoutSuccessHandler(logoutHandler)        ;        http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);    }    CorsConfigurationSource configurationSource() {        // 配置跨域        CorsConfiguration corsConfiguration = new CorsConfiguration();        corsConfiguration.setAllowedHeaders(Arrays.asList("*"));        corsConfiguration.setAllowedMethods(Arrays.asList("*"));        corsConfiguration.setMaxAge(3600L);        if (userSetting.getAllowedOrigins() != null && !userSetting.getAllowedOrigins().isEmpty()) {            corsConfiguration.setAllowCredentials(true);            corsConfiguration.setAllowedOrigins(userSetting.getAllowedOrigins());        }else {            corsConfiguration.setAllowCredentials(false);            corsConfiguration.setAllowedOrigins(Collections.singletonList(CorsConfiguration.ALL));        }        corsConfiguration.setExposedHeaders(Arrays.asList(JwtUtils.getHeader()));        UrlBasedCorsConfigurationSource url = new UrlBasedCorsConfigurationSource();        url.registerCorsConfiguration("/**", corsConfiguration);        return url;    }    /**     * 描述: 密码加密算法 BCrypt 推荐使用     **/    @Bean    public BCryptPasswordEncoder passwordEncoder() {        return new BCryptPasswordEncoder();    }    /**     * 描述: 注入AuthenticationManager管理器     **/    @Override    @Bean    public AuthenticationManager authenticationManager() throws Exception {        return super.authenticationManager();    }}
 |