Добавление параметров в заголовок не работает при реализации SpringBoot Security JWT для REST API - PullRequest
0 голосов
/ 10 марта 2020

Я пытаюсь реализовать аутентификацию и авторизацию с использованием токена JWT в SpringBoot REST API.

В моем классе JWTAuthentication

  @Override
  protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res,
      FilterChain chain, Authentication auth) throws IOException, ServletException {

    String token = Jwts.builder().setSubject(((User) auth.getPrincipal()).getUsername())
        .claim("roles", ((User) auth.getPrincipal()).getAuthorities())
        .setExpiration(new Date(System.currentTimeMillis() + SecurityConstants.EXPIRATION_TIME))
        .signWith(SignatureAlgorithm.HS512, SecurityConstants.SECRET.getBytes()).compact();
    res.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX + token);    
    chain.doFilter(req, res);
    System.out.println("Token:"+token);
  }

Когда я проверяю свой код, отправляя, отправляя следующее сообщение на URL 127.0.0.1:8080/login, я вижу, что аутентификация прошла успешно.

{"username":"admin", "password":"admin"}

И тогда Spring вызывает мой класс авторизации JWT

  @Override
  protected void doFilterInternal(
      HttpServletRequest req, HttpServletResponse res, FilterChain chain)
      throws IOException, ServletException {

    String header = req.getHeader(SecurityConstants.HEADER_STRING);

    if (header == null || !header.startsWith(SecurityConstants.TOKEN_PREFIX)) {
      if (header == null) {
        System.out.println("header null");
      } else if (!header.startsWith(SecurityConstants.TOKEN_PREFIX)) {
        System.out.println("token prefix missing in header");
      }
      chain.doFilter(req, res);
      return;
    }

    UsernamePasswordAuthenticationToken authentication = getAuthentication(req);

    SecurityContextHolder.getContext().setAuthentication(authentication);
    chain.doFilter(req, res);
  }

Он печатает сообщение: «Префикс токена отсутствует в заголовке»

Хотя я добавляю TOKEN_PREFIX в успешной аутентификации метод, он не может найти его в заголовке в методе doFilterInternal.

Кстати, моя конфигурация безопасности выглядит следующим образом:

@EnableWebSecurity(debug = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  @Autowired private UserDetailsService userDetailsService;
  @Autowired private BCryptPasswordEncoder bCryptPasswordEncoder;

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.cors()
        .and()
        .csrf()
        .disable()
        .authorizeRequests()
        .antMatchers("/admin/**")
        .hasRole("ADMIN")
        .anyRequest()
        .authenticated()
        .and()
        .addFilter(new JWTAuthenticationFilter(authenticationManager()))
        .addFilter(new JWTAuthorizationFilter(authenticationManager()))
        // this disables session creation on Spring Security
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
  }

  @Override
  public void configure(WebSecurity web) throws Exception {
    web.ignoring()
        .antMatchers(
            "/v2/api-docs",
            "/configuration/ui",
            "/swagger-resources/**",
            "/configuration/security",
            "/swagger-ui.html",
            "/webjars/**");
  }

  @Override
  public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
  }

  @Bean
  CorsConfigurationSource corsConfigurationSource() {
    final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
    return source;
  }
}

Я проверил книги SpringBoot, но не смог найти книга, которая описывает внутренние детали структуры безопасности. Поскольку я не понимал, как работает фреймворк, я не мог решить проблемы, просто просматривая блоги. Есть ли книга, в которой вы можете предложить подробные сведения о безопасности SpringBoot?

Спасибо

1 Ответ

0 голосов
/ 10 марта 2020

Вы устанавливаете свой токен после успешной аутентификации пользователя в заголовке Http ответа :

res.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX + token);    

Внутренний фильтр JWT (от того, что я понимаю в вашем вопросе, называется после твоего), смотрит в Http заголовки запроса

String header = req.getHeader(SecurityConstants.HEADER_STRING);

и там их нет.

В общем, второй фильтр не должен быть активным после того как вы аутентифицировали пользователя и должны просто вернуть токен JWT клиенту. Затем любой последующий вызов клиента должен включать токен JWT в заголовок Authorization, используя Bearer: YourJWTToken для вызова, например, защищенных API.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...