Маркер JWT в проблеме конфигурации Spring Boot - PullRequest
0 голосов
/ 05 ноября 2019

У меня проблема в том, что когда я звоню по запросу: localhost:8080/authenticate Безопасность моих приложений говорит о необходимости и токене. Когда запрос вызывается, фильтры проходят через него, так что это не намерение. Теперь служба безопасности запрашивает токен на предъявителя, пока это первый запрос и, конечно, его еще нет. Я получаю сообщение об ошибке JWT Token does not begin with Bearer String

Мой метод настройки:

@Override
    protected void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/authenticate");
    }

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .cors().disable()
                .authorizeRequests()
                .antMatchers("/authenticate").permitAll()
                .antMatchers("/**/private/**").authenticated()
                .anyRequest().permitAll()
                .and()
                .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class)
                .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint);
    }

Мой метод фильтрации:

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {

        final String requestTokenHeader = request.getHeader("Authorization");
        System.out.println("JWT Request: " + request.getRequestURI());
        System.out.println("JWT Contain: " + request.getRequestURI().contains("authenticate"));
        String username = null;
        String jwtToken = null;
        //Remove comment for second approach
        if (request.getRequestURI().contains("authenticate") == false) {
            System.out.println("Do Noting, Permit It");
            chain.doFilter(request, response);
        } else if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
            jwtToken = requestTokenHeader.substring(7);
            try {
                username = jwtTokenUtil.getUsernameFromToken(jwtToken);
            } catch (IllegalArgumentException e) {
                System.out.println("Unable to get JWT Token");
            } catch (ExpiredJwtException e) {
                System.out.println("JWT Token has expired");
            }
        } else {
            logger.warn("JWT Token does not begin with Bearer String");
        }

        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);
            }
        }
        chain.doFilter(request, response);
    }

Мой класс контроллера:

@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));
    }

    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public ResponseEntity<?> saveUser(@RequestBody UserDTO user) throws Exception {
        return ResponseEntity.ok(userDetailsService.save(user));
    }

    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);
        }
    }
}

Я хочу, чтобы программа работала так, чтобы при отправке запроса localhost:8080/authenticate фильтров не было, но при вызове каждого другого запроса будут фильтры для проверки наличия токена.

Заранее спасибо.

1 Ответ

1 голос
/ 05 ноября 2019

Переопределите метод configure(WebSecurity web), чтобы игнорировать конечную точку /authenticate, чтобы она не была включена в цепочку фильтров безопасности Spring, как показано ниже;

public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/authenticate");                
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...