Spring Security 配置
Spring Security 6 模式:SecurityFilterChain DSL、JWT 过滤器、BCrypt 密码编码、方法级安全和 CORS 配置。
1. SecurityFilterChain
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.csrf(csrf -> csrf.disable())
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/auth/**", "/public/**").permitAll()
.requestMatchers(HttpMethod.GET, "/articles/**").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
.build();
}
}
2. JWT 认证过滤器
@Component
public class JwtAuthFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain) throws ServletException, IOException {
String header = req.getHeader("Authorization");
if (header == null || !header.startsWith("Bearer ")) {
chain.doFilter(req, res);
return;
}
String token = header.substring(7);
String username = jwtService.extractUsername(token);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails user = userDetailsService.loadUserByUsername(username);
if (jwtService.isValid(token, user)) {
var auth = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(auth);
}
}
chain.doFilter(req, res);
}
}
3. 方法级安全
@DeleteMapping("/{id}")
@PreAuthorize("hasRole('ADMIN') or @articleSecurity.isOwner(#id, authentication)")
public void delete(@PathVariable Long id) { ... }
@Component("articleSecurity")
public class ArticleSecurity {
public boolean isOwner(Long articleId, Authentication auth) {
return repo.findById(articleId)
.map(a -> a.getAuthor().getUsername().equals(auth.getName()))
.orElse(false);
}
}
4. URL 授权表达式
| 表达式 | 含义 |
|---|---|
| permitAll() | 允许所有人 |
| authenticated() | 需要登录 |
| hasRole("ADMIN") | 具有 ROLE_ADMIN 权限 |
| hasAnyRole("A","B") | 具有任意指定角色 |
| anonymous() | 必须是匿名用户 |