Spring Security+JWT implements practical control of front-end and back-end separation permissions
In front-end and back-end separation projects, traditional Session-based authentication methods are no longer applicable. Instead, it is a lighter and more efficient JWT (JSON Web Token) method to achieve stateless authentication.
1. Why use JWT?
Challenges of front-end separation architecture:
- Unable to use Session to manage login status (front-end and back-end separation, cross-domain)
- Need a kind of "Stateless authentication mechanism」
Advantages of JWT:
- No need to store session information on the server (Token self-contained)
- Clear structure, support permission declarations
- Strong scalability, can be used in OAuth, SSO and other scenarios
2. Basic structure of JWT
A JWT Token is generally divided into three sections:
For example:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwiaWF0IjoxNjg3NjQ5fQ.K4KgD1sE0JQzA1K6k-FaSd56fQ
Each part functions:
part | content |
---|---|
Header | Signature algorithms, such as HS256 |
Payload | Payload (such as username, role, expiration time) |
Signature | Signature (prevent tampering) |
3. Spring Security permission control idea that integrates JWT
The overall process is as follows:
Front-end login -> Back-end verification user -> Generate JWT -> Return to front-end -> Front-end carry Token every request -> Back-end parsing verification and authorization
4. Core module code practice
1. Introducing dependencies (Spring Boot example)
<dependency> <groupId></groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId></groupId> <artifactId>jjwt-api</artifactId> <version>0.11.5</version> </dependency> <dependency> <groupId></groupId> <artifactId>jjwt-impl</artifactId> <version>0.11.5</version> <scope>runtime</scope> </dependency> <dependency> <groupId></groupId> <artifactId>jjwt-jackson</artifactId> <version>0.11.5</version> <scope>runtime</scope> </dependency>
2. JWT tool class
@Component public class JwtUtil { private final String SECRET = "MyJwtSecretKey123"; // It is recommended to put it in the configuration file private final long EXPIRATION = 1000 * 60 * 60; // 1 hour public String generateToken(String username) { return () .setSubject(username) .setIssuedAt(new Date()) .setExpiration(new Date(() + EXPIRATION)) .signWith(SignatureAlgorithm.HS256, SECRET) .compact(); } public String getUsernameFromToken(String token) { return ().setSigningKey(SECRET) .parseClaimsJws(token).getBody().getSubject(); } public boolean validateToken(String token) { try { ().setSigningKey(SECRET).parseClaimsJws(token); return true; } catch (Exception e) { return false; } } }
3. Custom login interface to generate token
@RestController public class AuthController { @Autowired private AuthenticationManager authenticationManager; @Autowired private JwtUtil jwtUtil; @PostMapping("/login") public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) { try { Authentication auth = ( new UsernamePasswordAuthenticationToken((), ()) ); String token = (()); return (("token", token)); } catch (AuthenticationException e) { return ().body("Error in username or password"); } } }
4. JWT certification filter
@Component public class JwtAuthFilter extends OncePerRequestFilter { @Autowired private JwtUtil jwtUtil; @Autowired private UserDetailsService userDetailsService; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { String authHeader = ("Authorization"); if (authHeader != null && ("Bearer ")) { String token = (7); String username = (token); if (username != null && ().getAuthentication() == null) { UserDetails userDetails = (username); if ((token)) { UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(userDetails, null, ()); (new WebAuthenticationDetailsSource().buildDetails(request)); ().setAuthentication(authToken); } } } (request, response); } }
5. Configure SecurityFilterChain
@Configuration @EnableMethodSecurity public class SecurityConfig { @Autowired private JwtAuthFilter jwtAuthFilter; @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { return http .csrf(csrf -> ()) .authorizeHttpRequests(auth -> auth .requestMatchers("/login").permitAll() .anyRequest().authenticated() ) .sessionManagement(session -> ()) .addFilterBefore(jwtAuthFilter, ) .build(); } @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception { return (); } }
5. How to use the front-end together?
- Save the returned one after logging in
token
- All subsequent requests are added in the header:
Authorization: Bearer <your token>
6. Permission control example
@RestController public class UserController { @PreAuthorize("hasRole('ADMIN')") @GetMapping("/admin/data") public String adminData() { return "Administrator data"; } @PreAuthorize("hasAnyRole('USER','ADMIN')") @GetMapping("/user/data") public String userData() { return "User Data"; } }
Summarize
The combination of JWT and Spring Security can help you build aStateless, safe and efficient front-end separation permission system. It simplifies the management process of login status and improves the scalability and concurrent processing capabilities of the system.
The above is personal experience. I hope you can give you a reference and I hope you can support me more.