Ad Code

✨🎆 JOIN MERN, JAVA, PYTHON, AI, DEVOPS, SALESFORCE Courses 🎆✨

Get 100% Placement Oriented Program CLICK to new more info click

JWT Authentication in Spring Boot API , How to implement this under Restful API , Detailed Explaination by Shiva Sir

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.springbootpractice.springbootproject.models;
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;
	    public String getUsername() {
			return username;
		}
		public void setUsername(String username) {
			this.username = username;
		}
		public String getPassword() {
			return password;
		}
		public void setPassword(String password) {
			this.password = password;
		}
		private String password;
	    private String role;
		public String getRole() {
			return role;
		}
		public void setRole(String role) {
			this.role = role;
		}
}


✅ 2. User Repository


p
package com.springbootpractice.springbootproject.respository;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
import com.springbootpractice.springbootproject.models.User;
public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByUsername(String username);
}

✅ 3. Custom UserDetailsService

package com.springbootpractice.springbootproject.services; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.*; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import com.springbootpractice.springbootproject.models.User; import com.springbootpractice.springbootproject.respository.UserRepository; @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.springbootpractice.springbootproject;
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


package com.springbootpractice.springbootproject;
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 com.springbootpractice.springbootproject.services.CustomUserDetailsService;

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) {
		String path = request.getRequestURI();
	    return path.startsWith("/auth")
	            || path.startsWith("/swagger-ui")
	            || path.startsWith("/v3/api-docs");
    }
	
	 @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);
	    }
	
}


Create Auth Controller:

package com.springbootpractice.springbootproject.controllers;

import com.springbootpractice.springbootproject.AuthRequest;
import com.springbootpractice.springbootproject.AuthResponse;
import com.springbootpractice.springbootproject.JwtUtil;
import com.springbootpractice.springbootproject.models.User;
import com.springbootpractice.springbootproject.respository.UserRepository;

import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.*;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/auth")
public class AuthController {

    private final AuthenticationManager authenticationManager;
    private final JwtUtil jwtUtil;
    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    public AuthController(AuthenticationManager authenticationManager,
                          JwtUtil jwtUtil,
                          UserRepository userRepository,
                          PasswordEncoder passwordEncoder) {
        this.authenticationManager = authenticationManager;
        this.jwtUtil = jwtUtil;
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
    }

    // =========================
    // LOGIN
    // =========================
    @PostMapping("/login")
    public ResponseEntity<AuthResponse> login(@RequestBody AuthRequest request) {
      System.out.println("hello login"+request.getPassword());
        authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                        request.getUsername(),
                        request.getPassword()
                )
        );

        String token = jwtUtil.generateToken(request.getUsername());
        System.out.println("hello login2"+request.getPassword() + "token is "+token);
        return ResponseEntity.ok(new AuthResponse(token));
    }

    // =========================
    // REGISTER
    // =========================
    @PostMapping("/register")
    public ResponseEntity<?> register(@RequestBody User user) {

        // Check if user already exists
        if (userRepository.findByUsername(user.getUsername()).isPresent()) {
            return ResponseEntity.badRequest()
                    .body("Username already exists!");
        }

        // Encrypt password
        user.setPassword(passwordEncoder.encode(user.getPassword()));

        // Default role
        if (user.getRole() == null) {
            user.setRole("USER");
        }

        userRepository.save(user);

        return ResponseEntity.ok("User Registered Successfully");
    }
}


Create Secure Controller to check Token Passing:
package com.springbootpractice.springbootproject.controllers;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/myapi")
public class SecureController {
@GetMapping("/hello")
    public String secured() {
        return "Secured API – JWT required";
    }
}




✅ Test APIs

🔓 Public


GET /public/hello

🔐 Login


POST /auth/login
{
  "username": "admin",
  "password": "admin123"
}

🔐 Secured


GET /api/hello
Authorization: Bearer <JWT_TOKEN>

View Complete Example

Post a Comment

0 Comments