Почему SpringBoot Security не возвращает никакого ответа клиенту REST, хотя аутентификация выполнена - PullRequest
0 голосов
/ 06 марта 2020

Я пытаюсь реализовать аутентификацию JWT с помощью REST API в SpringBoot. Когда я отлаживаю свой код, я вижу, что JWT Authenticator работает правильно, но я не вижу, чтобы код авторизации JWT вызывался средой Spring Security, и мой клиент REST не отправлял ответ. Ниже приведены некоторые части моего кода, которые, я думаю, связаны с моей проблемой.

Я думаю, что мой запрос теряется где-то в потоке Spring Security ...

WebSecurityConfig:

@EnableWebSecurity(debug = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

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

JWTAuthenticationFilter:

public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {


  public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
    setAuthenticationManager(authenticationManager);
  }

  @Override
  public Authentication attemptAuthentication(HttpServletRequest request,
      HttpServletResponse response) throws AuthenticationException {
    if (!HttpMethod.POST.matches(request.getMethod())) {
      throw new AuthenticationServiceException(
          "Authentication method not supported: " + request.getMethod());
    }

    try {
      JsonAuthenticationParser auth =
          new ObjectMapper().readValue(request.getInputStream(), JsonAuthenticationParser.class);
      System.out.println(auth.username);
      System.out.println(auth.password);
      UsernamePasswordAuthenticationToken authRequest =
          new UsernamePasswordAuthenticationToken(auth.username, auth.password);

      return this.getAuthenticationManager().authenticate(authRequest);
    } catch (Exception e) {
      log.warn("Auth failed!!!!!!!!!!!!");
      throw new InternalAuthenticationServiceException("Could not parse authentication payload");
    }
  }

  @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);
    System.out.println("Token:"+token);
  }

JWTAuthorizationFilter

public class JWTAuthorizationFilter extends BasicAuthenticationFilter {

  public JWTAuthorizationFilter(AuthenticationManager authManager) {
    super(authManager);
  }

  @Override
  protected void doFilterInternal(
      HttpServletRequest req, HttpServletResponse res, FilterChain chain)
      throws IOException, ServletException {
    System.out.println("++++++++++++++++++++++++++++AUTHERIZATION doFilterInternal++++++++++++++++++++++");

  }

  private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
    System.out.println("++++++++++++++++++++++++++++AUTHERIZATION getAuthentication++++++++++++++++++++++");

  }

1 Ответ

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

Фон

Когда вы добавляете фильтр в цепочку фильтров без указания порядка (http.addFilter(...)), компаратор HttpSecurity использует для определения своего порядка в цепочке взгляды на родительский класс фильтра. UsernamePasswordAuthenticationFilter предшествует BasicAuthenticationFilter (см. FilterComparator ).

Запрос приходит, достигает JWTAuthenticationFilter и «заканчивается» в методе successfulAuthentication().

Решение

Продолжить цепочку фильтров в JWTAuthenticationFilter:

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

    // ...

    chain.doFilter(req, res);

}
...