Spring boot 当使用nginix控制器将spring boot应用程序部署到kubernetes群集时,JWT身份验证不起作用
我有一个SpringBoot应用程序,带有端点POST/login,它验证凭据并在响应头中返回JWT。还有另一个端点/api/cars/listing,它需要具有有效JWT的授权头。此应用程序部署到具有3个节点的Kubernetes群集。之后,我在集群内为L7路由安装了ngnix入口控制器,并添加了入口资源 遵循本教程- 当我使用POST/login生成的JWT并将其用于GET/api/cars/listings时,我在响应中得到了403错误。是否需要在Nginx入口控制器中配置任何东西,以便根据请求IP将请求路由到同一节点Spring boot 当使用nginix控制器将spring boot应用程序部署到kubernetes群集时,JWT身份验证不起作用,spring-boot,kubernetes,jwt,kubernetes-ingress,nginx-ingress,Spring Boot,Kubernetes,Jwt,Kubernetes Ingress,Nginx Ingress,我有一个SpringBoot应用程序,带有端点POST/login,它验证凭据并在响应头中返回JWT。还有另一个端点/api/cars/listing,它需要具有有效JWT的授权头。此应用程序部署到具有3个节点的Kubernetes群集。之后,我在集群内为L7路由安装了ngnix入口控制器,并添加了入口资源 遵循本教程- 当我使用POST/login生成的JWT并将其用于GET/api/cars/listings时,我在响应中得到了403错误。是否需要在Nginx入口控制器中配置任何东西,以便根
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/login
GET/jwt/api/cars/listings查看kubectl日志后,发现问题与jwt密钥生成有关。每次spring boot应用程序重新启动时,都会动态生成密钥 我使用的是
Keys.secretKeyFor(SignatureAlgorithm.HS512)代码>在Spring配置文件中,如下所示。可以将其配置为部署环境变量或其他安全方式
@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);
}
}
查看kubectl日志后,发现问题与JWT密钥生成有关。每次spring boot应用程序重新启动时,都会动态生成密钥
我使用的是Keys.secretKeyFor(SignatureAlgorithm.HS512)代码>在Spring配置文件中,如下所示。可以将其配置为部署环境变量或其他安全方式
@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);
}
}
我猜您的应用程序有问题,因为NGINX几乎不向您的后端服务执行代理传递:请共享您基于JWT的应用程序的更多详细信息或日志application@prometherion是的,你是对的。问题似乎出在应用程序代码本身。JWT签名与本地计算的签名不匹配。无法断言JWT有效性,不应信任JWT有效性。在io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:383)~[jjwt-impl-0.10.5.jar:?]我猜您的应用程序有问题,因为NGINX几乎不执行到后端服务的代理传递:请共享基于JWT的应用程序的更多详细信息或日志application@prometherion是的,你是对的。问题似乎出在应用程序代码本身。JWT签名与本地计算的签名不匹配。无法断言JWT有效性,不应信任JWT有效性。在io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:383)~[jjwt-impl-0.10.5.jar:?]