SecurityConfig.java
2.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package com.xly.erp.common.config;
import com.xly.erp.common.security.JwtAuthenticationFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
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.SecurityFilterChain;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
* Spring Security 配置(docs/04 § 1.7)。
*
* <p>REQ-USR-001 T3:无状态 JWT 认证;放行 /api/usr/login、swagger、actuator/health,
* 其余需认证;注册 BCryptPasswordEncoder Bean;JwtAuthenticationFilter 挂在
* UsernamePasswordAuthenticationFilter 之前。</p>
*/
@Configuration
public class SecurityConfig {
/**
* 放行清单(无需 token 即可访问)。
*
* <p>REQ-USR-001 放行 /api/usr/login;REQ-USR-004 T5 追加 /api/usr/companies(登录页版本下拉)。
* 抽为常量供单测断言与过滤链共用,避免清单漂移。</p>
*/
public static final String[] PERMIT_ALL_PATHS = {
"/api/usr/login",
"/api/usr/companies",
"/swagger-ui/**",
"/swagger-ui.html",
"/v3/api-docs/**",
"/actuator/health",
};
/**
* 密码哈希编码器(BCrypt),禁止明文存储 / 比对。
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http,
JwtAuthenticationFilter jwtAuthenticationFilter)
throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.exceptionHandling(eh -> eh
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED)))
.authorizeHttpRequests(auth -> auth
.requestMatchers(PERMIT_ALL_PATHS)
.permitAll()
.anyRequest().authenticated())
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}