Аутентификация JWT не работает, когда приложение загрузки Spring развернуто в кластере kubernetes с контроллером nginix

У меня есть приложение для загрузки Spring с конечной точкой POST / login, которое проверяет учетные данные и возвращает JWT в заголовке ответа. Существует еще одна конечная точка / api / cars / листинг, для которой требуется заголовок авторизации с допустимым JWT. Это приложение развернуто в кластере Kubernetes с 3 узлами. После этого я установил контроллер входа ngnix для маршрутизации L7 в кластере и добавил ресурс входа.

Следовал этому руководству - https://cloud.google.com/community/tutorials/nginx-ingress-gke.

Когда я использую JWT, сгенерированный из POST / login, и использую его для GET / api / cars / listings, я получаю в ответе ошибку 403. Есть ли что-нибудь, что мне нужно настроить в контроллере входящего трафика Nginx для маршрутизации запроса к тому же узлу на основе IP-адреса запроса?

kind: Ingress
metadata:
  name: ingress-resource
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
 rules:
 - http:
    paths:
     - path: /jwt(/|$)(.*)
       backend:
        serviceName: jwt-app-service
        servicePort: 80

POST / jwt / логин

GET / jwt / api / cars / listings


person anusha rampally    schedule 15.10.2019    source источник
comment
Я предполагаю, что с вашим приложением что-то не так, потому что NGINX почти не выполняет прокси-передачу для вашей серверной службы: пожалуйста, поделитесь более подробной информацией или журналами вашего приложения на основе JWT   -  person prometherion    schedule 15.10.2019
comment
@prometherion Да, ты прав. Похоже, проблема в самом коде приложения. Подпись JWT не соответствует подписи, вычисленной локально. Правильность JWT нельзя утверждать и не следует доверять. в io.jsonwebtoken.impl.DefaultJwtParser.parse (DefaultJwtParser.java:383) ~ [jjwt-impl-0.10.5.jar :?]   -  person anusha rampally    schedule 15.10.2019


Ответы (1)


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

Я использовал Keys.secretKeyFor(SignatureAlgorithm.HS512); в файле конфигурации Spring, как показано ниже. Это можно настроить как переменную env развертывания или каким-либо другим безопасным способом.

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  private final JwtTokenService jwtTokenService;

  private AppUserDetailsService appUserDetailsService;

  @Autowired
  public SecurityConfig(AppUserDetailsService appUserDetailsService) {
    this.jwtTokenService = jwtTokenService();
    this.appUserDetailsService = appUserDetailsService;
  }

  public SecurityConfig() {
    this.jwtTokenService = jwtTokenService();
  }

  private Key base64EncodedSecretKey() {
    return Keys.secretKeyFor(SignatureAlgorithm.HS512);
  }


  private JwtTokenService jwtTokenService() {
    return new JwtTokenService(base64EncodedSecretKey());
  }


  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(this.appUserDetailsService)
        .passwordEncoder(NoOpPasswordEncoder.getInstance());
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    http.csrf().disable()
        .authorizeRequests()
        .antMatchers(HttpMethod.GET,"/greetings").permitAll()
        .antMatchers("/login").permitAll()
        .anyRequest()
        .authenticated()
        .and()
        .addFilterBefore(new LoginFilter("/login", this.jwtTokenService, authenticationManager()),
            UsernamePasswordAuthenticationFilter.class)
        .addFilterBefore(new JwtAuthenticationFilter(this.jwtTokenService, "/api/**"), UsernamePasswordAuthenticationFilter.class);


  }
}
person anusha rampally    schedule 15.10.2019