- Advantage of JSON token is it could be used form multiple platforms like PC, Mobile for accessing secured pages
- User enters user credentials(Username and Password) and gets authenticated.
- User Credentails are validated and token is generated
- On Subsequent request from APIs tokens are used in header for authorization
- Tokens are generated and verified by filters.There would be line of filters on way from request to API
- JwtUsernameAndPasswordAuthenticationFilter generates the Token after authentication
- JwtTokenVerifierFilter authorizes the user in each and every request by interpreting the token in the request header


JwtTokenVerifierFilter.java
public class JwtTokenVerifierFilter extends OncePerRequestFilter {
private final SecretKey secretKey;
private final JwtConfig jwtConfig;
public JwtTokenVerifierFilter(SecretKey secretKey,
JwtConfig jwtConfig) {
this.secretKey = secretKey;
this.jwtConfig = jwtConfig;
}
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
FilterChain filterChain) throws ServletException, IOException {
String authorizationHeader = httpServletRequest.getHeader(jwtConfig.getAuthorizationHeader());
if(Strings.isNullOrEmpty(authorizationHeader) || !authorizationHeader.startsWith("Bearer ")){
filterChain.doFilter(httpServletRequest, httpServletResponse);
return;
}
String token = authorizationHeader.replace(jwtConfig.getTokenPrefix(), "");
try{
Jws<Claims> claimsJws = Jwts.parser()
.setSigningKey(secretKey)
.parseClaimsJws(token);
Claims body = claimsJws.getBody();
String username = body.getSubject();
List<Map<String, String>> authorities = (List<Map<String, String>>)body.get("authorities");
Set<SimpleGrantedAuthority> simpleGrantedAuth = authorities.stream()
.map(m -> new SimpleGrantedAuthority(m.get("authority")))
.collect(Collectors.toSet());
Authentication authentication = new UsernamePasswordAuthenticationToken(username, null, simpleGrantedAuth);
SecurityContextHolder.getContext().setAuthentication(authentication);
}catch (JwtException e){
throw new IllegalStateException(String.format("Token %s cannot be Trusted", token));
}
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
}
JwtUsernameAndPasswordAuthenticationFilter.java
public class JwtUsernameAndPasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private final AuthenticationManager authenticationManager;
private final JwtConfig jwtConfig;
private final SecretKey secretKey;
public JwtUsernameAndPasswordAuthenticationFilter(AuthenticationManager authenticationManager,
JwtConfig jwtConfig,
SecretKey secretKey) {
this.authenticationManager = authenticationManager;
this.jwtConfig = jwtConfig;
this.secretKey = secretKey;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
try {
UsernameAndPasswordAuthenticationRequest authenticationRequest = new ObjectMapper()
.readValue(request.getInputStream(), UsernameAndPasswordAuthenticationRequest.class);
Authentication authentication = new UsernamePasswordAuthenticationToken(
authenticationRequest.getUsername(),
authenticationRequest.getPassword()
);
Authentication authenticate = authenticationManager.authenticate(authentication);
return authenticate;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected void successfulAuthentication(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain,
Authentication authResult) throws IOException, ServletException {
String token = Jwts.builder()
.setSubject(authResult.getName())
.claim("authorities", authResult.getAuthorities())
.setIssuedAt(new Date())
.setExpiration(java.sql.Date.valueOf(LocalDate.now().plusWeeks(jwtConfig.getTokenExpirationAfterDays())))
.signWith(secretKey)
.compact();
response.addHeader(jwtConfig.getAuthorizationHeader(), jwtConfig.getTokenPrefix() + token);
}
}