1
votes

Spring boot: Pourquoi utiliser OncePerRequestFilter?

J'ai une classe appelée JwtTokenAuthorizationOncePerRequestFilter où elle étend OncePerRequestFilter

Cependant, je rencontre un problème lorsque je me connecte, puis après une certaine utilisation de l'application Web

J'obtiens toujours "JWT_TOKEN_DOES_NOT_START_WITH_BEARER_STRING"

Voir le code ci-dessous:

package com.sbc.cpex.security.jwt;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import io.jsonwebtoken.ExpiredJwtException;

@Component
public class JwtTokenAuthorizationOncePerRequestFilter extends OncePerRequestFilter {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private UserDetailsService jwtInMemoryUserDetailsService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Value("${jwt.http.request.header}")
    private String tokenHeader;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        logger.debug("Authentication Request For '{}'", request.getRequestURL());

        final String requestTokenHeader = request.getHeader(this.tokenHeader);

        String username = null;
        String jwtToken = null;
        if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
            jwtToken = requestTokenHeader.substring(7);
            try {
                username = jwtTokenUtil.getUsernameFromToken(jwtToken);
            } catch (IllegalArgumentException e) {
                logger.error("JWT_TOKEN_UNABLE_TO_GET_USERNAME", e);
            } catch (ExpiredJwtException e) {
                logger.warn("JWT_TOKEN_EXPIRED", e);
            }
        } else {
            logger.warn("JWT_TOKEN_DOES_NOT_START_WITH_BEARER_STRING");
        }

        logger.debug("JWT_TOKEN_USERNAME_VALUE '{}'", username);
        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {

            UserDetails userDetails = this.jwtInMemoryUserDetailsService.loadUserByUsername(username);

            if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            }
        }

        chain.doFilter(request, response);
    }
}

Est-il possible pour moi de simplement déclencher cette classe lors de la connexion? Et pas lors de l'acceptation d'autres demandes

TIA


0 commentaires

3 Réponses :


0
votes

Eh bien, vous obtenez cet "avertissement" parce que vous avez cette ligne, si quelqu'un n'envoie pas de jeton porteur:

 logger.warn("JWT_TOKEN_DOES_NOT_START_WITH_BEARER_STRING");

Comme je suppose que vous protégez potentiellement toutes vos URL dans votre application, vous devrez faire fonctionner votre JWTFilter pour chaque URL.


4 commentaires

Si je supprime cette ligne, cela aura-t-il un impact sur la sécurité? Dois-je être constamment averti que le requestTokenHeader ne commence pas par "Bearer". Ou c'est tout à fait inoffensif. Merci de répondre.


Notez que j'envoie des demandes à mon point de terminaison en utilisant React. Et c'est dans le frontend où j'ajoute la chaîne "Bearer"


La ligne est juste une instruction de journal qui est déclenchée chaque fois que quelqu'un n'envoie pas de jeton de support avec une demande. La question est donc: pourquoi n'y a-t-il pas de jeton porteur qui entre?


Je pense que cela n'ajoute que le jeton de porteur lorsque la connexion est déclenchée. Mais à part cela, toutes les autres demandes ne sont pas accompagnées de jeton porteur.



0
votes

L'enregistreur avertit uniquement lors de la connexion car l'URL de la demande n'inclut pas encore de jeton de support. Les appels d'URL qui réussissent n'afficheront plus ce message d'avertissement si vous définissez le stockage de session pour le jeton avec le porteur plus le jeton généré lors de la connexion createAuthenticationToken


0 commentaires

0
votes

vous ne passez pas de jeton sur l'en-tête "Authorization" ou ce jeton que vous passez, ne commence pas par Bearer. Pensez à mettre le jeton create generate dans ces méthodes


0 commentaires