spring-boot - 当 Spring Boot 应用程序使用 nginx Controller 部署到 kubernetes 集群时,JWT 身份验证不起作用

标签 spring-boot kubernetes jwt kubernetes-ingress nginx-ingress

我有一个带有端点 POST/login 的 Spring boot 应用程序,它验证凭据并在响应 header 中返回 JWT。还有另一个端点/api/cars/listing 需要具有有效 JWT 的授权 header 。该应用程序部署到具有 3 个节点的 Kubernetes 集群。之后,我在集群中安装了用于 L7 路由的 ngnix 入口 Controller ,并添加了入口资源。

遵循本教程 - https://cloud.google.com/community/tutorials/nginx-ingress-gke

当我使用从 POST/login 生成的 JWT 并将其用于 GET/api/cars/listings 时,我在响应中收到 403 错误。我需要在 Nginx 入口 Controller 中配置什么才能根据请求 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/登录

获取/jwt/api/cars/listings

最佳答案

查看 kubectl 日志后,发现问题与 JWT key 生成有关。每次 Spring Boot 应用程序重新启动时,都会动态生成 key 。

我在 Spring 配置文件中使用了 Keys.secretKeyFor(SignatureAlgorithm.HS512); ,如下所示。这可以配置为部署环境变量或以其他某种安全方式。

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


  }
}

关于spring-boot - 当 Spring Boot 应用程序使用 nginx Controller 部署到 kubernetes 集群时,JWT 身份验证不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58400705/

相关文章:

spring - 如何运行Spring Boot快速启动代码

java - 如何使用 thymeleaf 在具有动态列的数据表中显示输入值

java - 如何禁用 Jackson 从 epoch millis 反序列化 Instant?

Kubernetes 工作节点处于未就绪状态

java - "Shared secret"用于 JWT 身份验证 SOA

java - spring boot - 如何正确定义模板位置?

dns - 如何为集群外的查询公开kube-dns服务?

javascript - 似乎无法将 Angular-JWT 注入(inject)工厂

javascript - 验证Token JWT是否有效

docker - 拉取镜像失败