JWTAuthenticationFilter
Créer le filtre
@Component
class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private JwtUtil jwtUtil;
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
FilterChain filterChain) throws ServletException, IOException {
// On récupère le token contenu dans le Header
final String authorizationHeader = httpServletRequest.getHeader("Authorization");
if (authorizationHeader == null || authorizationHeader.isEmpty() || !authorizationHeader.startsWith("Bearer")) {
// S'il n'existe pas alors on passe au filtre suivant
// C'est le cas pour le /login
filterChain.doFilter(httpServletRequest, httpServletResponse);
return;
}
final String token = authorizationHeader.split(" ")[1].trim();
if (!jwtUtil.validate(token)) {
// Si le token est invalide, alors on passe au filtre suivant
filterChain.doFilter(httpServletRequest, httpServletResponse);
return;
}
// Le token est valide
String username = jwtUtil.getUsername(token);
// On va créer une Authentication
UsernamePasswordAuthenticationToken upassToken = new UsernamePasswordAuthenticationToken(username, null,
new ArrayList<>());
upassToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
// On passe l'Authentication au Security Context
SecurityContextHolder.getContext().setAuthentication(upassToken);
// On appelle le filtre suivant
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
}
Ajouter le filtre à la SecurityFilterChain
On ajoute notre JwtAuthenticationFilter
avant le filtre UsernamePasswordAuthenticationFilter
.
@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity...
httpSecurity.addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
return httpSecurity.build();
}
Cas d'une requête quelconque
Dans le cas d'une requête quelconque nous :
- Vérifions quelle contienne une Authorization
- Vérifions que le token fourni est valide
- Si tel est le cas, alors nous créons une
Authentication
que nous ajoutons auSecurityContext
- Nous passons au filtre suivant
- Une fois tous les filtres exécutés, nous arriverons dans la methode exécutons la méthode appelée, par exemple
/restricted
Cas d'une requête de connexion
Dans le cas d'une requête /auth/login
nous n'avons pas de token donc nous rentrons dans le premier if
ce qui va exécuter les filtres suivants.
Une fois tous les filtres exécutés, nous arriverons dans la methode login()
où nous devrons :
- Créer un objet de type
Authentication
- Appeler le
AuthenticationManager
- Ajouter l'
AuthenticationManager
auSecurityContext
- Et, créer et renvoyer le JWT Token