Spring+Boot+Spring+Security+JWT+实现+RESTful+Api+认证+(一)
时间: 2023-10-02 07:06:49 浏览: 184
Spring Boot+Spring Security+JWT实现给RestApi增加认证控制
5星 · 资源好评率100%
Spring Boot和Spring Security可以很好地结合使用来实现RESTful API的认证。而JWT(JSON Web Token)是一种用于认证和授权的安全传输方式。
要在Spring Boot中实现JWT认证,可以遵循以下步骤:
1. 添加依赖:在`pom.xml`文件中添加以下依赖:
```xml
<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>
```
2. 创建JWT工具类:创建一个JWT工具类来生成和解析JWT。可以使用JJWT库来简化这个过程。
3. 创建认证过滤器:创建一个继承自`OncePerRequestFilter`的认证过滤器,在该过滤器中检查请求中的JWT,并进行认证。
4. 配置Spring Security:将认证过滤器添加到Spring Security的配置中,以便在每个请求到达之前进行JWT认证。
5. 创建登录接口:创建一个登录接口,用于验证用户的身份并生成JWT。
这是一个简单的示例代码,说明如何在Spring Boot中实现JWT认证:
```java
// JWT工具类
public class JwtUtils {
private static final String SECRET_KEY = "your-secret-key";
private static final long EXPIRATION_TIME = 864_000_000; // 10天
public static String generateToken(Authentication authentication) {
UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();
Date expirationDate = new Date(System.currentTimeMillis() + EXPIRATION_TIME);
return Jwts.builder()
.setSubject(userPrincipal.getUsername())
.setIssuedAt(new Date())
.setExpiration(expirationDate)
.signWith(SignatureAlgorithm.HS512, SECRET_KEY)
.compact();
}
public static String getUsernameFromToken(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody()
.getSubject();
}
public static boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
return true;
} catch (SignatureException | MalformedJwtException | ExpiredJwtException | UnsupportedJwtException | IllegalArgumentException e) {
return false;
}
}
}
// 认证过滤器
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JwtUtils jwtUtils;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String authorizationHeader = request.getHeader("Authorization");
if (StringUtils.hasText(authorizationHeader) && authorizationHeader.startsWith("Bearer ")) {
String token = authorizationHeader.substring(7);
if (jwtUtils.validateToken(token)) {
String username = jwtUtils.getUsernameFromToken(token);
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
filterChain.doFilter(request, response);
}
}
// Spring Security配置类
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
}
// 登录接口
@RestController
public class AuthController {
@Autowired
private AuthenticationManager authenticationManager;
@PostMapping("/login")
public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword())
);
SecurityContextHolder.getContext().setAuthentication(authentication);
String token = JwtUtils.generateToken(authentication);
return ResponseEntity.ok(new JwtResponse(token));
}
}
// 登录请求DTO
public class LoginRequest {
private String username;
private String password;
// getters and setters
}
// JWT响应DTO
public class JwtResponse {
private String token;
// constructor and getter
}
// 用户详情实现类
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("User Not Found with username: " + username));
return UserDetailsImpl.build(user);
}
}
```
阅读全文