| | |
| | | package com.genersoft.iot.vmp.conf.security; |
| | | |
| | | import com.genersoft.iot.vmp.conf.UserSetup; |
| | | import com.genersoft.iot.vmp.conf.UserSetting; |
| | | import org.springframework.core.annotation.Order; |
| | | 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.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; |
| | | |
| | | /** |
| | | * 配置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 UserSetup userSetup; |
| | | private UserSetting userSetting; |
| | | |
| | | @Autowired |
| | | private DefaultUserDetailsServiceImpl userDetailsService; |
| | | /** |
| | | * 登出成功的处理 |
| | | */ |
| | | @Autowired |
| | | private LoginFailureHandler loginFailureHandler; |
| | | /** |
| | | * 登录成功的处理 |
| | | */ |
| | | @Autowired |
| | | private LoginSuccessHandler loginSuccessHandler; |
| | | /** |
| | | * 登出成功的处理 |
| | | */ |
| | |
| | | */ |
| | | @Autowired |
| | | private AnonymousAuthenticationEntryPoint anonymousAuthenticationEntryPoint; |
| | | // /** |
| | | // * 超时处理 |
| | | // */ |
| | | // @Autowired |
| | | // private InvalidSessionHandler invalidSessionHandler; |
| | | |
| | | // /** |
| | | // * 顶号处理 |
| | | // */ |
| | | // @Autowired |
| | | // private SessionInformationExpiredHandler sessionInformationExpiredHandler; |
| | | // /** |
| | | // * 登录用户没有权限访问资源 |
| | | // */ |
| | | // @Autowired |
| | | // private LoginUserAccessDeniedHandler accessDeniedHandler; |
| | | @Autowired |
| | | private JwtAuthenticationFilter jwtAuthenticationFilter; |
| | | |
| | | |
| | | /** |
| | |
| | | **/ |
| | | @Override |
| | | public void configure(WebSecurity web) { |
| | | |
| | | if (!userSetup.isInterfaceAuthentication()) { |
| | | web.ignoring().antMatchers("**"); |
| | | }else { |
| | | if (userSetting.isInterfaceAuthentication()) { |
| | | ArrayList<String> matchers = new ArrayList<>(); |
| | | matchers.add("/"); |
| | | matchers.add("/#/**"); |
| | | matchers.add("/static/**"); |
| | | 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/*/**"); |
| | | // 可以直接访问的静态数据 |
| | | web.ignoring() |
| | | .antMatchers("/") |
| | | .antMatchers("/#/**") |
| | | .antMatchers("/static/**") |
| | | .antMatchers("/index.html") |
| | | .antMatchers("/doc.html") // "/webjars/**", "/swagger-resources/**", "/v3/api-docs/**" |
| | | .antMatchers("/webjars/**") |
| | | .antMatchers("/swagger-resources/**") |
| | | .antMatchers("/v3/api-docs/**") |
| | | .antMatchers("/js/**"); |
| | | web.ignoring().antMatchers(matchers.toArray(new String[0])); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | @Override |
| | | protected void configure(HttpSecurity http) throws Exception { |
| | | http.cors().and().csrf().disable(); |
| | | // 设置允许添加静态文件 |
| | | http.headers().contentTypeOptions().disable(); |
| | | http.authorizeRequests() |
| | | // 放行接口 |
| | | .antMatchers("/api/user/login","/index/hook/**").permitAll() |
| | | // 除上面外的所有请求全部需要鉴权认证 |
| | | .anyRequest().authenticated() |
| | | // 异常处理(权限拒绝、登录失效等) |
| | | .and().exceptionHandling() |
| | | .authenticationEntryPoint(anonymousAuthenticationEntryPoint)//匿名用户访问无权限资源时的异常处理 |
| | | // .accessDeniedHandler(accessDeniedHandler)//登录用户没有权限访问资源 |
| | | // 登入 |
| | | .and().formLogin().permitAll()//允许所有用户 |
| | | .successHandler(loginSuccessHandler)//登录成功处理逻辑 |
| | | .failureHandler(loginFailureHandler)//登录失败处理逻辑 |
| | | // 登出 |
| | | .and().logout().logoutUrl("/api/user/logout").permitAll()//允许所有用户 |
| | | .logoutSuccessHandler(logoutHandler)//登出成功处理逻辑 |
| | | .deleteCookies("JSESSIONID") |
| | | // 会话管理 |
| | | // .and().sessionManagement().invalidSessionStrategy(invalidSessionHandler) // 超时处理 |
| | | // .maximumSessions(1)//同一账号同时登录最大用户数 |
| | | // .expiredSessionStrategy(sessionInformationExpiredHandler) // 顶号处理 |
| | | ; |
| | | 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/**","/zlm_Proxy/FhTuMYqB2HeCuNOb/record/t/1/2023-03-25/16:35:07-16:35:16-9353.mp4").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); |
| | | corsConfiguration.setAllowCredentials(true); |
| | | corsConfiguration.setAllowedOrigins(userSetting.getAllowedOrigins()); |
| | | corsConfiguration.setExposedHeaders(Arrays.asList(JwtUtils.getHeader())); |
| | | |
| | | UrlBasedCorsConfigurationSource url = new UrlBasedCorsConfigurationSource(); |
| | | url.registerCorsConfiguration("/**",corsConfiguration); |
| | | return url; |
| | | } |
| | | |
| | | /** |