乐闻世界logo
搜索文章和话题

How can you secure REST APIs in a Spring Boot application using JSON Web Tokens ( JWT )?

1个答案

1

Protecting REST API in Spring Boot applications typically involves several key steps. Using JSON Web Tokens (JWT) is one of the most effective strategies for securing endpoints. I will now provide a detailed explanation of how to implement this approach, along with code examples to clarify the process.

Step 1: Add JWT Library Dependency

First, include the JWT library dependency in your Spring Boot project's pom.xml file. jjwt is a widely adopted Java library for generating and validating JWTs. For example:

xml
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency>

Step 2: Create JWT Utility Class

Develop a utility class JwtUtil to handle JWT generation and validation. This class manages:

  • Token creation
  • Token validity verification
  • Information extraction from tokens (e.g., username)
java
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import java.util.Date; import java.util.function.Function; public class JwtUtil { private String secretKey = "your_secret"; public String extractUsername(String token) { return extractClaim(token, Claims::getSubject); } public Date extractExpiration(String token) { return extractClaim(token, Claims::getExpiration); } public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) { final Claims claims = extractAllClaims(token); return claimsResolver.apply(claims); } private Claims extractAllClaims(String token) { return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody(); } private Boolean isTokenExpired(String token) { return extractExpiration(token).before(new Date()); } public String generateToken(String username) { return Jwts.builder().setSubject(username) .setIssuedAt(new Date(System.currentTimeMillis())) .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10)) .signWith(SignatureAlgorithm.HS256, secretKey).compact(); } public Boolean validateToken(String token, String username) { final String extractedUsername = extractUsername(token); return (username.equals(extractedUsername) && !isTokenExpired(token)); } }

Step 3: Implement JWT Request Filter

Create JwtRequestFilter extending OncePerRequestFilter to validate incoming requests for JWTs. If a request contains a valid JWT, access to protected resources is permitted.

java
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class JwtRequestFilter extends OncePerRequestFilter { @Autowired private UserDetailsService userDetailsService; @Autowired private JwtUtil jwtUtil; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { final String authorizationHeader = request.getHeader("Authorization"); String username = null; String jwt = null; if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) { jwt = authorizationHeader.substring(7); username = jwtUtil.extractUsername(jwt); } if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { UserDetails userDetails = this.userDetailsService.loadUserByUsername(username); if (jwtUtil.validateToken(jwt, userDetails.getUsername())) { UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken( userDetails, null, userDetails.getAuthorities()); SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); } } chain.doFilter(request, response); } }

Step 4: Configure Spring Security

Integrate the JWT filter into your Spring Security configuration. This involves adding the JWT filter to the security configuration class and setting HTTP security to restrict access to protected endpoints to requests with valid JWTs.

java
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @EnableWebSecurity public class SecurityConfigurer extends WebSecurityConfigurerAdapter { @Autowired private JwtRequestFilter jwtRequestFilter; @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests().antMatchers("/authenticate").permitAll() .anyRequest().authenticated() .and().sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS); http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class); } }

Step 5: Testing and Deployment

Finally, verify the JWT implementation through test cases and deploy the application in development or production environments.

By leveraging JWT for authentication and authorization, we ensure that only users possessing valid tokens can access protected resources, thereby strengthening the application's security.

2024年8月16日 00:49 回复

你的答案