在现代的Web应用中,用户认证和授权是非常重要的部分。Spring Boot与Spring Security结合JWT(JSON Web Token)可以非常方便地实现这一需求。本文将介绍如何使用Spring Boot、Spring Security与JWT实现一个简单的用户登录和权限认证功能。
1. 项目搭建
首先,需要创建一个Spring Boot项目,在pom.xml
中添加必要的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
2. 创建用户实体
我们需要一个用户实体类来代表系统中的用户:
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String roles; // 如 "ROLE_USER,ROLE_ADMIN"
// Getter和Setter
}
3. 创建用户服务
接下来,我们创建用户服务来处理用户的登录和注册:
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public User findByUsername(String username) {
return userRepository.findByUsername(username);
}
public User save(User user) {
return userRepository.save(user);
}
}
4. JWT工具类
我们需要一个工具类来生成和验证JWT:
@Component
public class JwtUtil {
private String secretKey = "secret";
public String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10)) // 10小时后过期
.signWith(SignatureAlgorithm.HS256, secretKey)
.compact();
}
public boolean validateToken(String token, String username) {
final String extractedUsername = extractUsername(token);
return (extractedUsername.equals(username) && !isTokenExpired(token));
}
public String extractUsername(String token) {
return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject();
}
private boolean isTokenExpired(String token) {
return extractExpiration(token).before(new Date());
}
private Date extractExpiration(String token) {
return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getExpiration();
}
}
5. 安全配置
接下来,配置Spring Security来使用JWT:
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtRequestFilter jwtRequestFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/authenticate").permitAll() // 允许访问的接口
.anyRequest().authenticated(); // 其他请求需要认证
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
}
6. 认证控制器
最后,我们创建一个控制器来处理登录请求,并返回JWT:
@RestController
public class AuthController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtUtil jwtUtil;
@Autowired
private UserService userService;
@PostMapping("/authenticate")
public ResponseEntity<?> authenticate(@RequestBody AuthRequest authRequest) {
try {
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(authRequest.getUsername(), authRequest.getPassword())
);
} catch (AuthenticationException e) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("用户认证失败");
}
final String jwt = jwtUtil.generateToken(authRequest.getUsername());
return ResponseEntity.ok(new AuthResponse(jwt));
}
}
7. 测试与总结
现在,我们可以使用Postman等工具来测试我们的接口。首先,启动Spring Boot应用程序,然后发送POST请求到/authenticate
接口,附带JSON格式的用户名和密码。如果用户名和密码正确,将会返回JWT令牌。
通过使用JWT,确保我们的用户身份在每次请求中得到验证,从而保护了API的安全性。
整体而言,Spring Boot与Spring Security结合JWT是一种非常强大且灵活的解决方案,适合用来实现用户的认证与授权。希望本文能够帮助你理解如何构建一个基于JWT的用户认证系统。