Implementing Spring Security with JSON web token
Experienced Spring Boot Developer with over 3+ years of expertise in developing scalable and high-performance web applications and microservices. Proficient in Java and Spring Boot frameworks, with hands- on experience in RESTful APIs and Microservices architecture. Adept at building secure, database-driven applications and integrating various third- party services. Strong problem-solving skills with a focus on delivering clean, maintainable, and efficient code.
Let’s start with a very basic project which has a simple @RestController UserControler. UserControler has a method mapped with @GetMapping which returns String “Hello, World!” when api ( http://localhost:8020/api/hello ) is hit.
As of now we have only added spring-boot-starter-web dependency to our project.


Let’s start by implementing Spring Security -
Step 0 → Add dependencies in pom file.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
Authentication and Authorization of Request happens in multiple steps -


Step 1 → Request is intercepted by the Controller
Request is intercepted by “login” method which maps request data into an Object Model JwtRequest.
“login” method first makes a call to “doAuthenticate” method which uses “AuthenticationManager“ to validate user. “AuthenticationManager” calls “authenticate“ method to validate user.
If user is validated successfully then “login” method will generate a JWT Token for the user and return that token as response, otherwise exception with message "Credentials Invalid !!" will be thrown as a response.
@RestController
@RequestMapping("/auth")
public class AuthController {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private AuthenticationManager manager;
@Autowired
private JwtHelper helper;
private Logger logger = LoggerFactory.getLogger(AuthController.class);
@PostMapping("/login")
public ResponseEntity<JwtResponse> login(@RequestBody JwtRequest request) {
this.doAuthenticate(request.getEmail(), request.getPassword());
UserDetails userDetails = userDetailsService.loadUserByUsername(request.getEmail());
String token = this.helper.generateToken(userDetails);
JwtResponse response = JwtResponse.builder()
.jwtToken(token)
.username(userDetails.getUsername()).build();
return new ResponseEntity<>(response, HttpStatus.OK);
}
private void doAuthenticate(String email, String password) {
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(email, password);
try {
manager.authenticate(authentication);
} catch (BadCredentialsException e) {
throw new BadCredentialsException(" Invalid Username or Password !!");
}
}
@ExceptionHandler(BadCredentialsException.class)
public String exceptionHandler() {
return "Credentials Invalid !!";
}
}
Step 2 → Configure Authentication using “AuthenticationManagerBuilder”.
- We have to tell “AuthenticationManager“ how to do Authentication (Ex - Basic, OAuth, JWT, etc). We do that by creating a configuration class which extends “AuthenticationManagerBuilder“ and overrides “configure” method.