generated from Java-2025Fall/final-vibevault-template
更新 src/main/java/com/vibevault/config/SecurityConfig.java
This commit is contained in:
parent
d6fb6fac4c
commit
16896dee2c
@ -1,15 +1,16 @@
|
||||
package com.vibevault.config;
|
||||
|
||||
import com.vibevault.security.JwtAuthenticationFilter;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||
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.http.SessionCreationPolicy;
|
||||
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;
|
||||
@ -17,9 +18,9 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
|
||||
|
||||
/**
|
||||
* Spring Security 配置
|
||||
*
|
||||
* 需要实现:
|
||||
* - 公开接口无需认证:/api/auth/**, GET /api/playlists, GET /api/playlists/{id}
|
||||
*
|
||||
* 需要实现:
|
||||
* - 公开接口无需认证: /api/auth/**, GET /api/playlists, GET /api/playlists/{id}
|
||||
* - 其他接口需要认证
|
||||
* - 未认证访问受保护资源返回 401(不是 403)
|
||||
* - 配置 JWT 过滤器
|
||||
@ -32,26 +33,68 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
|
||||
public class SecurityConfig {
|
||||
|
||||
private final JwtAuthenticationFilter jwtAuthenticationFilter;
|
||||
private final UserDetailsService userDetailsService;
|
||||
|
||||
public SecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter) {
|
||||
// 构造注入过滤器和用户详情服务
|
||||
public SecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter, UserDetailsService userDetailsService) {
|
||||
this.jwtAuthenticationFilter = jwtAuthenticationFilter;
|
||||
this.userDetailsService = userDetailsService;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
// TODO: 配置安全规则
|
||||
// 提示:
|
||||
// - 使用 http.authorizeHttpRequests() 配置路径权限
|
||||
// - 使用 http.csrf(csrf -> csrf.disable()) 禁用 CSRF
|
||||
// - 使用 http.sessionManagement() 配置无状态会话
|
||||
// - 使用 http.exceptionHandling() 配置 401 响应
|
||||
// - 使用 http.addFilterBefore() 添加 JWT 过滤器
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
// 配置密码编码器
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
}
|
||||
|
||||
// 配置认证提供者
|
||||
@Bean
|
||||
public DaoAuthenticationProvider authenticationProvider() {
|
||||
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
|
||||
authProvider.setUserDetailsService(userDetailsService);
|
||||
authProvider.setPasswordEncoder(passwordEncoder());
|
||||
return authProvider;
|
||||
}
|
||||
|
||||
// 配置认证管理器
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
|
||||
return config.getAuthenticationManager();
|
||||
}
|
||||
|
||||
// 核心安全过滤链配置
|
||||
@Bean
|
||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
http
|
||||
// 1. 禁用CSRF(REST API不需要)
|
||||
.csrf(csrf -> csrf.disable())
|
||||
|
||||
// 2. 配置接口权限
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
// 公开接口无需认证
|
||||
.requestMatchers("/api/auth/**").permitAll()
|
||||
.requestMatchers("GET", "/api/playlists").permitAll()
|
||||
.requestMatchers("GET", "/api/playlists/{id}").permitAll()
|
||||
// 其他接口需要认证
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
|
||||
// 3. 未认证返回401(默认行为,确保不被覆盖)
|
||||
.exceptionHandling(ex -> ex
|
||||
.authenticationEntryPoint((request, response, authException) -> {
|
||||
response.setStatus(401);
|
||||
response.getWriter().write("Unauthorized: " + authException.getMessage());
|
||||
})
|
||||
)
|
||||
|
||||
// 4. 使用无状态会话(JWT不需要会话)
|
||||
.sessionManagement(session -> session
|
||||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
)
|
||||
|
||||
// 5. 配置JWT过滤器(在用户名密码过滤器之前执行)
|
||||
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user