|
|
@@ -0,0 +1,149 @@
|
|
|
+package top.imwork.window.silos.security.config;
|
|
|
+
|
|
|
+import jakarta.annotation.Resource;
|
|
|
+import org.springframework.context.annotation.Bean;
|
|
|
+import org.springframework.context.annotation.Configuration;
|
|
|
+import org.springframework.security.authentication.AuthenticationManager;
|
|
|
+import org.springframework.security.authentication.AuthenticationProvider;
|
|
|
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
|
|
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
|
|
+import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
|
|
+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.WebSecurityConfiguration;
|
|
|
+import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
|
|
|
+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.SecurityFilterChain;
|
|
|
+import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
|
|
+import org.springframework.web.cors.CorsConfiguration;
|
|
|
+import org.springframework.web.cors.CorsConfigurationSource;
|
|
|
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
|
|
+import top.imwork.window.silos.security.details.SecurityUserDetailsService;
|
|
|
+import top.imwork.window.silos.security.handler.SecurityAuthenticationFailureHandler;
|
|
|
+import top.imwork.window.silos.security.handler.SecurityAuthenticationSuccessHandler;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Copyright (C), 2015-2025
|
|
|
+ * FileName: SecurityConfig
|
|
|
+ * Author<作者姓名>: stars
|
|
|
+ * CreateTime<创建时间>: 2025/12/10 13:31
|
|
|
+ * UpdateTime<修改时间>: 2025/12/10 13:31
|
|
|
+ * Description〈功能简述〉: 配置类
|
|
|
+ * History<历史描述>: 注意:security底层就是使用过滤器,一共有16个过滤器,称为过滤器链;
|
|
|
+ * Since<版本号>: 1.0.0
|
|
|
+ */
|
|
|
+@Configuration
|
|
|
+@EnableWebSecurity
|
|
|
+@EnableMethodSecurity(prePostEnabled = true)
|
|
|
+public class SecurityConfig{
|
|
|
+ @Resource
|
|
|
+ private SecurityUserDetailsService userDetailsService;
|
|
|
+ @Resource
|
|
|
+ private SecurityAuthenticationSuccessHandler authenticationSuccessHandler;
|
|
|
+ @Resource
|
|
|
+ private SecurityAuthenticationFailureHandler authenticationFailureHandler;
|
|
|
+
|
|
|
+ @Bean
|
|
|
+ public PasswordEncoder passwordEncoder() {
|
|
|
+ return new BCryptPasswordEncoder();
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 配置跨源访问(CORS)
|
|
|
+ *
|
|
|
+ * @return CorsConfigurationSource
|
|
|
+ */
|
|
|
+ @Bean
|
|
|
+ public CorsConfigurationSource corsConfigurationSource() {
|
|
|
+ UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
|
|
+ source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
|
|
|
+ return source;
|
|
|
+ }
|
|
|
+ @Bean
|
|
|
+ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
|
|
+ http.authorizeHttpRequests(authorize -> authorize
|
|
|
+ //需要放行的地址
|
|
|
+ // 静态资源
|
|
|
+ .requestMatchers("/static/**", "/assets/**", "/business/**").permitAll()
|
|
|
+ //登录/注册页面
|
|
|
+ .requestMatchers("/login", "/login.html", "/silos/login.html", "/auth/login", "/", "/register").permitAll()
|
|
|
+ // 公开访问的API
|
|
|
+ .requestMatchers("/api/public/**").permitAll()
|
|
|
+ // Swagger文档
|
|
|
+ .requestMatchers("/swagger-ui/**", "/v3/api-docs/**", "/swagger-resources/**").permitAll()
|
|
|
+ // 其他所有请求都需要认证
|
|
|
+ .anyRequest().authenticated()
|
|
|
+ )
|
|
|
+ .headers(headers -> headers
|
|
|
+ .frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin)
|
|
|
+ )
|
|
|
+ .formLogin(form -> form
|
|
|
+ .loginPage("/login.html") // 登录页面
|
|
|
+ .loginProcessingUrl("/auth/login") // 登录处理URL
|
|
|
+ .usernameParameter("username")
|
|
|
+ .passwordParameter("password")
|
|
|
+ .successHandler(authenticationSuccessHandler)
|
|
|
+ .failureHandler(authenticationFailureHandler)
|
|
|
+ .permitAll())
|
|
|
+ // 其他配置
|
|
|
+ /*.csrf(csrf -> csrf
|
|
|
+ .ignoringRequestMatchers("/api/public/**")
|
|
|
+ )*/
|
|
|
+ .csrf(csrf -> csrf
|
|
|
+ .disable()
|
|
|
+ )
|
|
|
+ .logout(logout -> logout
|
|
|
+ .logoutUrl("/api/auth/logout")
|
|
|
+ .logoutSuccessHandler(logoutSuccessHandler())
|
|
|
+ .invalidateHttpSession(true)
|
|
|
+ .deleteCookies("JSESSIONID")
|
|
|
+ .permitAll()
|
|
|
+ )
|
|
|
+ .sessionManagement(session -> session
|
|
|
+ .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
|
|
|
+ .maximumSessions(1)
|
|
|
+ .maxSessionsPreventsLogin(false)
|
|
|
+ )
|
|
|
+ .rememberMe(remember -> remember
|
|
|
+ .key("uniqueAndSecret")
|
|
|
+ .tokenValiditySeconds(86400) // 24小时
|
|
|
+ .userDetailsService(userDetailsService)
|
|
|
+ )
|
|
|
+ .exceptionHandling(exceptions -> exceptions
|
|
|
+ .accessDeniedPage("/access-denied")
|
|
|
+ )
|
|
|
+ .authenticationProvider(authenticationProvider());
|
|
|
+ return http.build();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Bean
|
|
|
+ public LogoutSuccessHandler logoutSuccessHandler() {
|
|
|
+ return (request, response, authentication) -> {
|
|
|
+ response.setContentType("application/json;charset=UTF-8");
|
|
|
+ response.getWriter().write("{\"success\": true, \"message\": \"退出成功\"}");
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ @Bean
|
|
|
+ public AuthenticationProvider authenticationProvider() {
|
|
|
+ DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
|
|
|
+ authProvider.setUserDetailsService(userDetailsService);
|
|
|
+ authProvider.setPasswordEncoder(passwordEncoder());
|
|
|
+ return authProvider;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Bean
|
|
|
+ public AuthenticationManager authenticationManager(
|
|
|
+ HttpSecurity http, PasswordEncoder passwordEncoder) throws Exception {
|
|
|
+
|
|
|
+ AuthenticationManagerBuilder authenticationManagerBuilder =
|
|
|
+ http.getSharedObject(AuthenticationManagerBuilder.class);
|
|
|
+
|
|
|
+ authenticationManagerBuilder
|
|
|
+ .userDetailsService(userDetailsService)
|
|
|
+ .passwordEncoder(passwordEncoder);
|
|
|
+
|
|
|
+ return authenticationManagerBuilder.build();
|
|
|
+ }
|
|
|
+}
|