What is JWT Token?
JWT = JSON Web Token
JWT is a secure way to authenticate users in a stateless manner (server does not remember user session).
JWT is a digital identity card sent by the server to the client after login,
which the client sends back on every request to prove who they are.
JWT Format xxxxx.yyyyy.zzzzz
❌ Old Session-Based Auth
Login → Server creates session → Session stored in server memory
✅ JWT-Based Auth
Login → Server creates token → Client stores token → No session stored
Step-by-step Flow
1️⃣ Client sends username & password
2️⃣ Server validates credentials
3️⃣ Server generates JWT token
4️⃣ Client stores JWT token
5️⃣ Client sends token with every request
6️⃣ Server validates token
7️⃣ If valid → access granted
🔐 Why JWT is Secure?
✔ Digitally signed
✔ Cannot be modified
✔ Has expiry time
✔ Server verifies signature every time
❌ No token → ❌ No access
✅ 1. User Entity
package com.example.jwt.entity;
import jakarta.persistence.*;
import lombok.Data;
@Entity
@Data
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String role;
}
✅ 2. User Repository
package com.example.jwt.repository;
import com.example.jwt.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username);
}
✅ 3. Custom UserDetailsService
package com.example.jwt.service;
import com.example.jwt.entity.User;
import com.example.jwt.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.*;
import org.springframework.stereotype.Service;
@Service
public class CustomUserDetailsService 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"));
return org.springframework.security.core.userdetails.User
.withUsername(user.getUsername())
.password(user.getPassword())
.roles(user.getRole())
.build();
}
}
✅ 4. JWT Utility
package com.example.jwt.util;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class JwtUtil {
private static final String SECRET_KEY =
"mysecretkeymysecretkeymysecretkey123";
public String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 60 * 60 * 1000))
.signWith(Keys.hmacShaKeyFor(SECRET_KEY.getBytes()), SignatureAlgorithm.HS256)
.compact();
}
public String extractUsername(String token) {
return Jwts.parserBuilder()
.setSigningKey(SECRET_KEY.getBytes())
.build()
.parseClaimsJws(token)
.getBody()
.getSubject();
}
public boolean isTokenValid(String token) {
try {
Jwts.parserBuilder()
.setSigningKey(SECRET_KEY.getBytes())
.build()
.parseClaimsJws(token);
return true;
} catch (Exception e) {
return false;
}
}
}
✅ 5. JWT Filter (Public URLs Excluded)
package com.example.jwt.filter;
import com.example.jwt.service.CustomUserDetailsService;
import com.example.jwt.util.JwtUtil;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.*;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.util.List;
@Component
public class JwtAuthFilter extends OncePerRequestFilter {
@Autowired
private JwtUtil jwtUtil;
@Autowired
private CustomUserDetailsService userDetailsService;
private static final List<String> PUBLIC_URLS = List.of(
"/auth/",
"/public/",
"/swagger-ui/",
"/v3/api-docs"
);
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
return PUBLIC_URLS.stream()
.anyMatch(url -> request.getRequestURI().startsWith(url));
}
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
String authHeader = request.getHeader("Authorization");
if (authHeader != null && authHeader.startsWith("Bearer ")) {
String token = authHeader.substring(7);
String username = jwtUtil.extractUsername(token);
if (username != null &&
SecurityContextHolder.getContext().getAuthentication() == null) {
var userDetails =
userDetailsService.loadUserByUsername(username);
if (jwtUtil.isTokenValid(token)) {
UsernamePasswordAuthenticationToken authToken =
new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authToken.setDetails(
new WebAuthenticationDetailsSource()
.buildDetails(request));
SecurityContextHolder.getContext()
.setAuthentication(authToken);
}
}
}
filterChain.doFilter(request, response);
}
}
✅ 6. Security Configuration
package com.example.jwt.config;
import com.example.jwt.filter.JwtAuthFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.*;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableMethodSecurity
public class SecurityConfig {
@Autowired
private JwtAuthFilter jwtAuthFilter;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http)
throws Exception {
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers(
"/auth/**",
"/public/**",
"/swagger-ui/**",
"/v3/api-docs/**"
).permitAll()
.anyRequest().authenticated()
)
.sessionManagement(session ->
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
);
http.addFilterBefore(jwtAuthFilter,
UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public AuthenticationManager authenticationManager(
AuthenticationConfiguration config) throws Exception {
return config.getAuthenticationManager();
}
}
✅ 7. Auth DTOs
package com.example.jwt.dto;
import lombok.Data;
@Data
public class AuthRequest {
private String username;
private String password;
}
package com.example.jwt.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class AuthResponse {
private String token;
}
✅ 8. Auth Controller (Login – No JWT)
package com.example.jwt.controller;
import com.example.jwt.dto.*;
import com.example.jwt.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.*;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/auth")
public class AuthController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtUtil jwtUtil;
@PostMapping("/login")
public ResponseEntity<AuthResponse> login(
@RequestBody AuthRequest request) {
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
request.getUsername(),
request.getPassword())
);
String token = jwtUtil.generateToken(request.getUsername());
return ResponseEntity.ok(new AuthResponse(token));
}
}
✅ 9. Public Controller (NO JWT)
package com.example.jwt.controller;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/public")
public class PublicController {
@GetMapping("/hello")
public String hello() {
return "Public API – No JWT required";
}
}
✅ 10. Secure Controller (JWT REQUIRED)
package com.example.jwt.controller;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
public class SecureController {
@GetMapping("/hello")
public String secured() {
return "Secured API – JWT required";
}
}
✅ 11. Test APIs
🔓 Public
GET /public/hello
🔐 Login
POST /auth/login
{
"username": "admin",
"password": "admin123"
}
🔐 Secured
GET /api/hello
Authorization: Bearer <JWT_TOKEN>
0 Comments
POST Answer of Questions and ASK to Doubt