
一、前言
安全性是任何后端系统的核心。Spring Security 是 Spring 生态中专门用于提供身份认证与访问控制的强大框架,适用于 Web、微服务、REST 接口等场景。
本篇将带你了解 Spring Security 的认证授权机制,掌握常见的使用方式,并结合 JWT 实现前后端分离的登录方案。
二、Spring Security 能做什么?
Spring Security 提供以下功能:
- 用户认证(Authentication)
- 权限授权(Authorization)
- 密码加密(BCrypt)
- 会话管理、记住我
- 防止 CSRF、Session Fixation
- 与 OAuth2、JWT 等机制集成
三、核心概念
名称 | 说明 |
---|---|
SecurityContext | 安全上下文,存储当前登录用户信息 |
Authentication | 用户的认证信息(用户名、密码、角色) |
UserDetails | 自定义用户信息类 |
UserDetailsService | 获取用户信息的数据来源(如数据库) |
GrantedAuthority | 用户的权限集合 |
四、Spring Security 入门示例
引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
默认开启 Basic 登录页面,访问任何接口都需要登录。
五、自定义用户名密码登录逻辑
1. 自定义用户详情类
public class MyUserDetails implements UserDetails {
private User user; // 用户对象可来自数据库
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return AuthorityUtils.createAuthorityList("ROLE_USER");
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
// 其他 isAccountNonExpired 等返回 true
}
2. 实现 UserDetailsService
@Service
public class MyUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) {
// 查询数据库
User user = userRepository.findByUsername(username);
return new MyUserDetails(user);
}
}
3. 配置 Security
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyUserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin().permitAll()
.and()
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());
}
}
六、密码加密:BCrypt
Spring Security 推荐使用 BCryptPasswordEncoder
进行密码加密。
String hash = new BCryptPasswordEncoder().encode("123456");
认证时自动对比密码哈希值,无需手动验证。
七、基于 JWT 的前后端分离登录方案
1. 用户登录成功后生成 JWT
String token = Jwts.builder()
.setSubject(user.getUsername())
.setExpiration(new Date(System.currentTimeMillis() + 3600000))
.signWith(SignatureAlgorithm.HS512, secretKey)
.compact();
2. 客户端保存并在每次请求中发送
Authorization: Bearer <token>
3. 自定义过滤器解析 Token
public class JwtAuthenticationFilter extends OncePerRequestFilter {
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) {
String header = req.getHeader("Authorization");
if (header != null && header.startsWith("Bearer ")) {
String token = header.substring(7);
String username = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getSubject();
// 设置到上下文
}
chain.doFilter(req, res);
}
}
4. 注入过滤器
http.addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
八、角色与权限控制
@PreAuthorize("hasRole('ADMIN')")
@GetMapping("/admin/dashboard")
public String dashboard() {
return "管理员页面";
}
在控制层注解权限控制,适配前后端分离应用。
九、安全防护机制
- CSRF 防护:默认启用,可关闭(适用于 API 项目)
- Session 管理:支持最大登录数、并发踢人
- Remember Me:记住我功能
- Logout 清除:安全退出,清空上下文
十、总结
Spring Security 是企业级安全的基础设施:
- 基于过滤器链进行身份验证与访问控制
- 支持多种认证方式(表单登录、JWT、OAuth2)
- 可扩展性强,适用于 Web、微服务、API 等多种场景
下一篇将聚焦于异步任务和调度:
《Spring 定时任务与异步编程:@Scheduled 与 @Async 实战》
是否继续生成第 7 篇?