0
votes

I am new to the micro-services architecture , I am building application using SpringBoot and wanted to add JWT auth for my APIs .

Ref link : https://dzone.com/articles/spring-boot-security-json-web-tokenjwt-hello-world

I was wondering if I should separate out the authentication / authorization code from the business-micro-service(BMS) . So each time a rest API call to BMS would in turn call the auth-microservice for validation . Would this be a good practice or would it be a lot on the network traffic ?

Calls might look like :

Client -> BusinessApp -> AuthMS -> Business App -> Client

The reason of separating it out is that there is some configuration and code that would not look good coupled with business app , but I am unsure of the network cost it would take for each API call.

Example code in JWT app which would make sense to be in different service / server running ? :

import java.util.Objects;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.javainuse.service.JwtUserDetailsService;
import com.javainuse.config.JwtTokenUtil;
import com.javainuse.model.JwtRequest;
import com.javainuse.model.JwtResponse;
@RestController
@CrossOrigin
public class JwtAuthenticationController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Autowired
private JwtUserDetailsService userDetailsService;
@RequestMapping(value = "/authenticate", method = RequestMethod.POST)
public ResponseEntity<?> createAuthenticationToken(@RequestBody JwtRequest authenticationRequest) throws Exception {
authenticate(authenticationRequest.getUsername(), authenticationRequest.getPassword());
final UserDetails userDetails = userDetailsService
.loadUserByUsername(authenticationRequest.getUsername());
final String token = jwtTokenUtil.generateToken(userDetails);
return ResponseEntity.ok(new JwtResponse(token));
}
private void authenticate(String username, String password) throws Exception {
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
} catch (DisabledException e) {
throw new Exception("USER_DISABLED", e);
} catch (BadCredentialsException e) {
throw new Exception("INVALID_CREDENTIALS", e);
}
}
}
1

1 Answers

2
votes

It is a good practice to let your api gateway handle all the authorization requests. The request will pass through the api gateway where it will be validated and only then have access to the micro-service (where the business logic is there). Let your gateway take care of the following:

(1) validate tokens with every request (2) prevent all unauthenticated requests to the services

Check this out for more details