金币系统后端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

140 lines
5.8 KiB

4 months ago
  1. package com.example.demo.security;
  2. import com.example.demo.domain.vo.Result;
  3. import jakarta.servlet.http.HttpServletResponse;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.Configuration;
  7. import org.springframework.http.HttpMethod;
  8. import org.springframework.security.authentication.AuthenticationManager;
  9. import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
  10. import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
  11. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  12. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
  13. import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
  14. import org.springframework.security.config.http.SessionCreationPolicy;
  15. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  16. import org.springframework.security.crypto.password.PasswordEncoder;
  17. import org.springframework.security.web.AuthenticationEntryPoint;
  18. import org.springframework.security.web.SecurityFilterChain;
  19. import org.springframework.security.web.access.AccessDeniedHandler;
  20. import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
  21. import org.springframework.web.cors.CorsConfiguration;
  22. import org.springframework.web.cors.CorsConfigurationSource;
  23. import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
  24. /**
  25. * SpringSecurity的配置文件
  26. */
  27. @Configuration
  28. @EnableWebSecurity // 开启Security的支持
  29. @EnableGlobalMethodSecurity(prePostEnabled = true) // 开启方法注解
  30. public class SecurityConfig {
  31. @Autowired
  32. TokenFilter tokenFilter;
  33. // 核心配置 配置一个过滤器链
  34. @Bean
  35. public SecurityFilterChain configure(HttpSecurity http) throws Exception {
  36. // 这里可以对httpSecurity进行详细的配置 链式调用的配置方式
  37. http.formLogin(AbstractHttpConfigurer::disable) // 方法引用,禁用表单登录
  38. .logout(AbstractHttpConfigurer::disable) // 禁用默认退出
  39. .csrf(AbstractHttpConfigurer::disable) // 禁用csrf的保护,分布式的前后端分离的项目
  40. // 设定CORS
  41. .cors(cors -> cors.configurationSource(corsConfigurationSource()))
  42. // 禁用Session,
  43. .sessionManagement( session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
  44. // 用户未登录的处理
  45. .exceptionHandling( exception -> exception.authenticationEntryPoint(authenticationEntryPoint()))
  46. // 用户权限不足的处理
  47. .exceptionHandling( exception -> exception.accessDeniedHandler(accessDeniedHandler()))
  48. // 配置路径拦截
  49. .authorizeHttpRequests( request ->
  50. request
  51. .requestMatchers( HttpMethod.POST,
  52. // 用户不登录就可以访问的路径
  53. "/admin/login","/upload/**","/detailY/ERP").permitAll()
  54. .requestMatchers(
  55. "/error","alipay/**","/upload/**"
  56. ).permitAll()
  57. .anyRequest().authenticated() // 其它路径,必须要登录后才能访问
  58. );
  59. http.addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class); // 然后是TokenFilter
  60. return http.build();
  61. }
  62. /**
  63. * 1. 配置认证管理器
  64. * @param config
  65. * @return
  66. * @throws Exception
  67. */
  68. @Bean
  69. protected AuthenticationManager authenticationManager(
  70. AuthenticationConfiguration config ) throws Exception {
  71. return config.getAuthenticationManager();
  72. }
  73. /**
  74. * 2. 密码编码器
  75. * @return
  76. */
  77. @Bean
  78. public PasswordEncoder passwordEncoder() {
  79. return new BCryptPasswordEncoder();
  80. }
  81. /**
  82. * 3. 用户未登录时的错误处理
  83. * @return
  84. */
  85. @Bean
  86. public AuthenticationEntryPoint authenticationEntryPoint() {
  87. return ( request, response, authException) -> {
  88. response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 401
  89. response.setContentType("application/json; charset=utf-8");
  90. response.getWriter().write(Result.error("用户未登录").toJson());
  91. };
  92. }
  93. /**
  94. * 4. 权限不足时的处理
  95. * @return
  96. */
  97. @Bean
  98. public AccessDeniedHandler accessDeniedHandler() {
  99. return ( request, response, authException) -> {
  100. response.setStatus(HttpServletResponse.SC_FORBIDDEN); // 403
  101. response.setContentType("application/json; charset=utf-8");
  102. response.getWriter().write(Result.error("当前用户权限不足!").toJson());
  103. };
  104. }
  105. /**
  106. * 5. 配置跨域请求
  107. * @return
  108. */
  109. @Bean
  110. public CorsConfigurationSource corsConfigurationSource() {
  111. CorsConfiguration config = new CorsConfiguration();
  112. config.addAllowedOriginPattern("*"); // 允许任何的源
  113. config.addAllowedMethod("*"); // 允许任何的HTTP请求方式
  114. config.addAllowedHeader("*"); // 允许任何的HTTP头
  115. config.setAllowCredentials(true); // 允许证书
  116. config.setMaxAge(3600L); // 设置浏览器预检的时间
  117. // 生成源
  118. UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
  119. source.registerCorsConfiguration("/**", config);
  120. return source;
  121. }
  122. }