parent
ba952bb1f8
commit
fce631eb3c
@ -0,0 +1,78 @@
|
||||
package edu.ahbvc.recruit.aspect;
|
||||
|
||||
import edu.ahbvc.recruit.annotation.SwitchMethod;
|
||||
import edu.ahbvc.recruit.model.ApiResponseData;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @author c215
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
public class MethodSwitch {
|
||||
// 使用常量定义功能类型
|
||||
// 注册
|
||||
public static final String REGISTER = "register";
|
||||
// 提交简历
|
||||
public static final String SUBMIT = "submit";
|
||||
// 尝试重新提交
|
||||
public static final String TRY_SUBMIT = "trySubmit";
|
||||
// 放弃投递
|
||||
public static final String ABANDON = "abandon";
|
||||
|
||||
// 使用带有默认值的线程安全的Map存储开关状态
|
||||
private static final Map<String, Boolean> METHOD_SWITCHES = new ConcurrentHashMap<>();
|
||||
|
||||
// 静态代码块,在类加载时执行,用于初始化开关状态
|
||||
static {
|
||||
// 默认情况下,所有功能都启用
|
||||
METHOD_SWITCHES.put(REGISTER, true);
|
||||
METHOD_SWITCHES.put(SUBMIT, true);
|
||||
METHOD_SWITCHES.put(TRY_SUBMIT, true);
|
||||
METHOD_SWITCHES.put(ABANDON, true);
|
||||
}
|
||||
|
||||
// 统一设置方法
|
||||
// 通过此方法可以动态地设置功能的开关状态
|
||||
public static void setSwitch(String methodType, boolean enabled) {
|
||||
// 检查方法类型是否存在
|
||||
if (!METHOD_SWITCHES.containsKey(methodType)) {
|
||||
throw new IllegalArgumentException("Invalid method type: " + methodType);
|
||||
}
|
||||
// 设置功能的开关状态
|
||||
METHOD_SWITCHES.put(methodType, enabled);
|
||||
}
|
||||
|
||||
// 统一获取方法
|
||||
// 通过此方法可以获取功能的开关状态
|
||||
public static boolean isEnabled(String methodType) {
|
||||
// 检查方法类型是否存在
|
||||
if (!METHOD_SWITCHES.containsKey(methodType)) {
|
||||
throw new IllegalArgumentException("Invalid method type: " + methodType);
|
||||
}
|
||||
// 返回功能的开关状态
|
||||
return METHOD_SWITCHES.getOrDefault(methodType, false);
|
||||
}
|
||||
|
||||
// 统一切面处理
|
||||
@Around("@annotation(switchMethod)")
|
||||
public Object controlMethod(ProceedingJoinPoint joinPoint, SwitchMethod switchMethod) throws Throwable {
|
||||
// 获取方法的功能类型
|
||||
String methodType = switchMethod.value();
|
||||
// 检查功能是否启用
|
||||
if (!METHOD_SWITCHES.getOrDefault(methodType, false)) {
|
||||
// 如果功能未启用,则返回错误信息
|
||||
return new ApiResponseData<>("500", null, "此功能已关闭");
|
||||
}
|
||||
// 如果功能已启用,则执行原方法
|
||||
return joinPoint.proceed();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,80 @@
|
||||
package edu.ahbvc.recruit.config;
|
||||
|
||||
import edu.ahbvc.recruit.util.JwtUtil;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* JWT请求过滤器
|
||||
* 用于处理JWT认证请求
|
||||
* 继承自OncePerRequestFilter, 确保每个请求只被过滤一次
|
||||
* 实现了doFilterInternal方法, 用于处理请求的认证逻辑
|
||||
* 从请求头中获取JWT令牌, 并验证令牌的有效性
|
||||
* 如果令牌有效, 则将用户信息设置到SecurityContextHolder中, 以便后续的认证和授权操作
|
||||
* 如果令牌无效, 则不做任何操作
|
||||
* 因为JWT相关代码暂未更新, 所以此类用不到
|
||||
* 更新了之后代码量更少了,所以屎山了, 但是功能是有的, 所以就先这样了, 以后再优化
|
||||
* @author c215
|
||||
*/
|
||||
|
||||
// * JWT请求过滤器
|
||||
// * 用于处理JWT认证请求
|
||||
// * 继承自OncePerRequestFilter, 确保每个请求只被过滤一次
|
||||
// * 实现了doFilterInternal方法, 用于处理请求的认证逻辑
|
||||
// * 从请求头中获取JWT令牌, 并验证令牌的有效性
|
||||
// * 如果令牌有效, 则将用户信息设置到SecurityContextHolder中, 以便后续的认证和授权操作
|
||||
// * 如果令牌无效, 则不做任何操作
|
||||
// * 因为JWT相关代码暂未更新, 所以此类用不到
|
||||
// * 更新了之后代码量更少了,所以屎山了, 但是功能是有的, 所以就先这样了, 以后再优化
|
||||
|
||||
@Component
|
||||
public class JwtRequestFilter {
|
||||
// extends OncePerRequestFilter
|
||||
// @Autowired
|
||||
// private UserDetailsService userDetailsService;
|
||||
//
|
||||
// @Autowired
|
||||
// private JwtUtil jwtUtil;
|
||||
//
|
||||
// @Override
|
||||
// protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
|
||||
// throws ServletException, IOException {
|
||||
//
|
||||
// final String authorizationHeader = request.getHeader("Authorization");
|
||||
//
|
||||
// String username = null;
|
||||
// String jwt = null;
|
||||
//
|
||||
// if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
|
||||
// jwt = authorizationHeader.substring(7);
|
||||
// username = jwtUtil.extractUsername(jwt);
|
||||
// }
|
||||
//
|
||||
// if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||
//
|
||||
// UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
|
||||
//
|
||||
// if (jwtUtil.validateToken(jwt, userDetails)) {
|
||||
//
|
||||
// UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
|
||||
// userDetails, null, userDetails.getAuthorities());
|
||||
// usernamePasswordAuthenticationToken
|
||||
// .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||
// SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
|
||||
// }
|
||||
// }
|
||||
// chain.doFilter(request, response);
|
||||
// }
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package edu.ahbvc.recruit.config;
|
||||
|
||||
|
||||
import edu.ahbvc.recruit.mapper.UserInter;
|
||||
import edu.ahbvc.recruit.model.token.CustomUserDetailsService;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.authentication.CachingUserDetailsService;
|
||||
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.core.userdetails.UserDetailsService;
|
||||
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.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.web.cors.CorsConfigurationSource;
|
||||
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.CorsConfigurationSource;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
import static org.springframework.security.config.Customizer.withDefaults;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* Spring Security配置类
|
||||
* @author c215
|
||||
*/
|
||||
// @Configuration 表示这是一个配置类
|
||||
@Configuration
|
||||
// @EnableWebSecurity 表示启用Spring Security的Web安全支持
|
||||
@EnableWebSecurity
|
||||
public class Security {
|
||||
// SecurityFilterChain 用于配置安全过滤器链
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.csrf(AbstractHttpConfigurer::disable)
|
||||
.cors(withDefaults())
|
||||
.authorizeHttpRequests((requests)->requests
|
||||
.requestMatchers("/","/login","/favicon.ico","/**").permitAll()
|
||||
.anyRequest().authenticated()
|
||||
|
||||
)
|
||||
.formLogin((form)-> form
|
||||
.loginPage("/login.html")
|
||||
.permitAll()
|
||||
);
|
||||
return http.build();
|
||||
}
|
||||
|
||||
|
||||
// CORS 配置源 用于配置跨域请求的CORS配置
|
||||
// 正式上线后需要修改为允许指定的域名和端口
|
||||
@Bean
|
||||
CorsConfigurationSource corsConfigurationSource() {
|
||||
CorsConfiguration configuration = new CorsConfiguration();
|
||||
// 允许所有本地地址和端口
|
||||
configuration.setAllowedOriginPatterns(Arrays.asList(
|
||||
"http://localhost:*",
|
||||
"http://127.0.0.1:*"
|
||||
));
|
||||
// 允许所有请求方法
|
||||
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
|
||||
// 允许所有请求头
|
||||
configuration.setAllowedHeaders(Collections.singletonList("*"));
|
||||
// 允许携带凭证
|
||||
configuration.setAllowCredentials(true);
|
||||
|
||||
// 注册CORS配置源
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
// 注册CORS配置源
|
||||
source.registerCorsConfiguration("/**", configuration);
|
||||
return source;
|
||||
}
|
||||
|
||||
// UserDetailsService 用于加载用户信息
|
||||
// 因为JWT相关代码暂未更新, 所以此方法用不到
|
||||
@Bean
|
||||
public UserDetailsService userDetailsService(UserInter userRepository){
|
||||
return new CustomUserDetailsService(userRepository);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder(){
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package edu.ahbvc.recruit.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* Web配置
|
||||
* @author c215
|
||||
*/
|
||||
@Configuration
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
// 配置跨域请求的CORS配置
|
||||
// 正式上线后需要修改为允许指定的域名和端口
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**")
|
||||
// 允许所有本地地址和端口
|
||||
.allowedOrigins("http://localhost:3333")
|
||||
// 允许的请求方法
|
||||
.allowedMethods("GET", "POST", "PUT", "DELETE")
|
||||
// 允许的请求头
|
||||
.allowedHeaders("*")
|
||||
// 允许凭证
|
||||
.allowCredentials(true)
|
||||
// 预检请求的缓存时间
|
||||
.maxAge(3600);
|
||||
}
|
||||
|
||||
// 配置静态资源的处理
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
// 配置静态资源的处理
|
||||
// 允许访问的路径
|
||||
registry.addResourceHandler("/**")
|
||||
// 允许访问的路径
|
||||
.addResourceLocations("classpath:/static/");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in new issue