Spring Security 回顾一
Spring Security 框架介绍
1. Spring Security 是什么?
Spring Security 是 Spring 框架的安全管理框架,用于提供 身份认证(Authentication) 和 授权(Authorization) 机制。它主要用于保护 Web 应用 和 REST API,防止 未授权访问 和 常见安全攻击(如 CSRF、XSS、Session Fixation、Clickjacking 等)。
2. Spring Security 的核心概念
Spring Security 主要涉及以下核心概念:
2.1 身份认证(Authentication)
身份认证是指 验证用户身份 的过程。Spring Security 支持多种认证方式:
- 用户名 + 密码(默认基于
UserDetailsService
) - JWT 令牌(适用于 REST API)
- OAuth 2.0 / OpenID Connect(支持 Google、GitHub 等第三方登录)
- LDAP(企业级身份认证)
- SSO(单点登录)
- 自定义认证提供者(Custom AuthenticationProvider)
2.2 授权(Authorization)
授权是指 确定用户是否有权限访问资源 的过程。Spring Security 主要有两种授权方式:
- 基于角色(Role-Based Access Control, RBAC):
- 例如:
hasRole('ADMIN')
- 例如:
- 基于权限(Permission-Based Access Control, PBAC):
- 例如:
hasAuthority('READ_PRIVILEGE')
- 例如:
授权方式:
- 方法级别授权(基于
@PreAuthorize
,@Secured
) - URL 级别授权(基于
HttpSecurity
) - 自定义授权逻辑
2.3 安全过滤器(Security Filters)
Spring Security 采用 过滤器链(Filter Chain) 进行请求拦截,每个请求都会经过 多个安全过滤器:
- UsernamePasswordAuthenticationFilter(处理表单登录)
- BasicAuthenticationFilter(处理 HTTP Basic 认证)
- JwtAuthenticationFilter(自定义 JWT 认证)
- SecurityContextPersistenceFilter(管理用户 Session)
- ExceptionTranslationFilter(异常处理)
2.4 Spring Security 的安全特性
- CSRF 保护(Cross-Site Request Forgery)
- Session 管理(防止会话固定攻击)
- 密码加密(BCryptPasswordEncoder)
- 跨域资源共享(CORS)支持
- 两步验证(2FA)
- 安全头部管理(Security Headers)
3. Spring Security 的基本使用
3.1 添加 Spring Security 依赖
如果使用 Spring Boot,可以直接添加 spring-boot-starter-security
:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
3.2 配置简单的用户名密码登录
Spring Security 默认提供一个 UserDetailsService
,默认用户名是 user
,密码在控制台生成。我们可以自定义用户名密码:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/admin/**").hasRole("ADMIN") // 只有 ADMIN 角色可以访问
.requestMatchers("/user/**").hasRole("USER") // 只有 USER 角色可以访问
.anyRequest().authenticated() // 其他请求必须登录
)
.formLogin(withDefaults()) // 启用默认的登录表单
.httpBasic(withDefaults()); // 启用 HTTP Basic 认证
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("admin")
.password("admin123")
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user);
}
}
4. Spring Security + JWT 实现无状态认证
对于 REST API,我们通常使用 JWT(JSON Web Token) 进行无状态认证,而不是 Session 机制。
4.1 添加 JWT 依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.11.5</version>
</dependency>
4.2 实现 JWT 生成和解析
@Component
public class JwtUtil {
private final String SECRET_KEY = "my_secret_key";
public String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60)) // 1小时
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
public String extractUsername(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody()
.getSubject();
}
public boolean validateToken(String token, UserDetails userDetails) {
return userDetails.getUsername().equals(extractUsername(token));
}
}
4.3 JWT 过滤器
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private JwtUtil jwtUtil;
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
String token = request.getHeader("Authorization");
if (token != null && token.startsWith("Bearer ")) {
token = token.substring(7);
String username = jwtUtil.extractUsername(token);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (jwtUtil.validateToken(token, userDetails)) {
UsernamePasswordAuthenticationToken authToken =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
}
chain.doFilter(request, response);
}
}
4.4 在 SecurityConfig 中注册 JWT 过滤器
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Autowired
private JwtAuthenticationFilter jwtFilter;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable) // 关闭 CSRF(因为是无状态的)
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
)
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class); // 加入 JWT 过滤器
return http.build();
}
}
5. 总结
Spring Security 是 Spring 生态系统中最强大的安全框架,它提供了:
✅ 强大的身份认证和授权机制
✅ 默认安全策略,防止常见攻击
✅ 支持多种认证方式(JWT、OAuth2、LDAP、SSO)
✅ 可扩展的安全过滤器链
对于 Web 应用,可以使用 默认表单登录 或 OAuth2 登录;
对于 REST API,推荐使用 JWT 进行无状态认证。
如果你正在开发 Spring Boot 应用,Spring Security 是 最推荐的安全框架!🚀