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
140 lines
5.8 KiB
package com.example.demo.security;
|
|
|
|
|
|
|
|
import com.example.demo.domain.vo.Result;
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
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.annotation.authentication.configuration.AuthenticationConfiguration;
|
|
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.configurers.AbstractHttpConfigurer;
|
|
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.AuthenticationEntryPoint;
|
|
import org.springframework.security.web.SecurityFilterChain;
|
|
import org.springframework.security.web.access.AccessDeniedHandler;
|
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
|
import org.springframework.web.cors.CorsConfiguration;
|
|
import org.springframework.web.cors.CorsConfigurationSource;
|
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
|
|
|
/**
|
|
* SpringSecurity的配置文件
|
|
*/
|
|
@Configuration
|
|
|
|
@EnableWebSecurity // 开启Security的支持
|
|
@EnableGlobalMethodSecurity(prePostEnabled = true) // 开启方法注解
|
|
|
|
public class SecurityConfig {
|
|
|
|
|
|
@Autowired
|
|
TokenFilter tokenFilter;
|
|
|
|
|
|
// 核心配置 配置一个过滤器链
|
|
@Bean
|
|
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
|
|
// 这里可以对httpSecurity进行详细的配置 链式调用的配置方式
|
|
http.formLogin(AbstractHttpConfigurer::disable) // 方法引用,禁用表单登录
|
|
.logout(AbstractHttpConfigurer::disable) // 禁用默认退出
|
|
.csrf(AbstractHttpConfigurer::disable) // 禁用csrf的保护,分布式的前后端分离的项目
|
|
// 设定CORS
|
|
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
|
|
// 禁用Session,
|
|
.sessionManagement( session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
|
// 用户未登录的处理
|
|
.exceptionHandling( exception -> exception.authenticationEntryPoint(authenticationEntryPoint()))
|
|
// 用户权限不足的处理
|
|
.exceptionHandling( exception -> exception.accessDeniedHandler(accessDeniedHandler()))
|
|
// 配置路径拦截
|
|
.authorizeHttpRequests( request ->
|
|
request
|
|
.requestMatchers( HttpMethod.POST,
|
|
// 用户不登录就可以访问的路径
|
|
"/admin/login","/upload/**","/detailY/ERP").permitAll()
|
|
.requestMatchers(
|
|
"/error","alipay/**","/upload/**"
|
|
).permitAll()
|
|
.anyRequest().authenticated() // 其它路径,必须要登录后才能访问
|
|
);
|
|
|
|
http.addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class); // 然后是TokenFilter
|
|
|
|
return http.build();
|
|
}
|
|
|
|
/**
|
|
* 1. 配置认证管理器
|
|
* @param config
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
@Bean
|
|
protected AuthenticationManager authenticationManager(
|
|
AuthenticationConfiguration config ) throws Exception {
|
|
return config.getAuthenticationManager();
|
|
}
|
|
|
|
/**
|
|
* 2. 密码编码器
|
|
* @return
|
|
*/
|
|
@Bean
|
|
public PasswordEncoder passwordEncoder() {
|
|
return new BCryptPasswordEncoder();
|
|
}
|
|
|
|
/**
|
|
* 3. 用户未登录时的错误处理
|
|
* @return
|
|
*/
|
|
@Bean
|
|
public AuthenticationEntryPoint authenticationEntryPoint() {
|
|
return ( request, response, authException) -> {
|
|
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 401
|
|
response.setContentType("application/json; charset=utf-8");
|
|
response.getWriter().write(Result.error("用户未登录").toJson());
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 4. 权限不足时的处理
|
|
* @return
|
|
*/
|
|
@Bean
|
|
public AccessDeniedHandler accessDeniedHandler() {
|
|
return ( request, response, authException) -> {
|
|
response.setStatus(HttpServletResponse.SC_FORBIDDEN); // 403
|
|
response.setContentType("application/json; charset=utf-8");
|
|
response.getWriter().write(Result.error("当前用户权限不足!").toJson());
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 5. 配置跨域请求
|
|
* @return
|
|
*/
|
|
@Bean
|
|
public CorsConfigurationSource corsConfigurationSource() {
|
|
CorsConfiguration config = new CorsConfiguration();
|
|
config.addAllowedOriginPattern("*"); // 允许任何的源
|
|
config.addAllowedMethod("*"); // 允许任何的HTTP请求方式
|
|
config.addAllowedHeader("*"); // 允许任何的HTTP头
|
|
config.setAllowCredentials(true); // 允许证书
|
|
config.setMaxAge(3600L); // 设置浏览器预检的时间
|
|
|
|
// 生成源
|
|
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
|
source.registerCorsConfiguration("/**", config);
|
|
return source;
|
|
}
|
|
}
|