Spring Boot, Spring Security - проверяйте JWT, только если URL отличается - PullRequest
0 голосов
/ 03 февраля 2020

Требуется проверить, является ли JWT действительным - для всех URL, кроме этих. Независимо от того, является ли заголовок авторизации пустым или содержит недопустимый JWT, просто игнорируйте его, если URL-адрес запроса является одним из следующих:

"/authenticate", "/users/sign_up", "/users/activate_account/*"

WebSecurityConfig. java

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Autowired
  private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;

  @Autowired
  private JwtRequestFilter jwtRequestFilter;

  @Override
  protected void configure(HttpSecurity httpSecurity) throws Exception {

    httpSecurity.csrf().disable()
                .authorizeRequests()
                .antMatchers(
                    "/authenticate", "/users/sign_up", "/users/activate_account/*"  
                ).permitAll()
                .anyRequest().authenticated()
                .and()
                .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

       httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
  }

}

JwtRequestFilter. java

@Component
public class JwtRequestFilter extends OncePerRequestFilter {

@Autowired
private JwtUserDetailsService jwtUserDetailsService;

private final JwtToken jwtTokenUtil;    

public JwtRequestFilter(JwtToken jwtTokenUtil) {
    this.jwtTokenUtil = jwtTokenUtil;
}

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {

    final String requestTokenHeader = request.getHeader("Authorization");
    String username = null;
    String jwtToken = null;

    // Need to know somehow whether the url needs JWT check or not

    /* Get username from header token */

    if (requestTokenHeader == null) {
        logger.warn("Blank JWT");
    } else if (!requestTokenHeader.startsWith("Bearer ")) {
        logger.warn("Invalid JWT token - doesn't contain Bearer");
    } else {
        jwtToken = requestTokenHeader.substring(7);         
        try {               
            username = jwtTokenUtil.getUsernameFromToken(jwtToken);             
        } catch (IllegalArgumentException e) {
            logger.error("Unable to get JWT");
        } catch (ExpiredJwtException e) {
            logger.error("JWT has timed out");
        }           
    } 

    /* Config set up w.r.t username */

    if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {

        UserDetails userDetails = this.jwtUserDetailsService.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);
        }
    }

    filterChain.doFilter(request, response);
}

} `

Проблема: Когда я отправляю пустое заголовок авторизации, работает нормально. Но когда я отправляю неверный заголовок даже для разрешенных URL, он выдает исключение JWT.

Я хочу проверить правильность токена JWT, только если URL-адрес отличается от упомянутых. Это возможно? Потому что интерфейс сохраняет JWT в cook ie и отправляет его при каждом запросе.

...