我正在尝试在 Spring Boot 应用程序中创建一个端点,以由 pubsub 消息调用。
该应用程序已经为通过 firebase 登录的用户启用了一些安全性。 安全配置看起来像这样
http
.cors(AbstractHttpConfigurer::disable)
.csrf(AbstractHttpConfigurer::disable)
.anonymous(anon -> anon.authorities("ROLE_ANONYMOUS"))
.authorizeHttpRequests((auth) -> auth.requestMatchers("/pubsub").permitAll())
.authorizeHttpRequests((auth) -> auth.anyRequest().authenticated())
.oauth2ResourceServer((oauth2)-> oauth2.jwt(c-> c.jwtAuthenticationConverter(customizer)));
我面临的问题是,即使我出于安全原因离开了
pubsub
端点,spring仍然尝试验证jwt,这本身就很好,但它失败了,这就是问题所在。
2023-11-21T12:48:01.964-05:00 DEBUG 52865 --- [nio-9090-exec-1] o.s.s.o.s.r.a.JwtAuthenticationProvider : Failed to authenticate since the JWT was invalid
JWT 显然是有效的,我可以自己检查。
我认为问题是我如何配置 spring boot 来验证配置中这一行的 jwt
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://www.googleapis.com/service_accounts/v1/jwk/securetoken%40system.gserviceaccount.com
知道如何整合这两个 jwt 令牌验证吗?
经过大约八个小时的尝试,我找到了答案。
我离得很远,所以显然在帖子的设置中,即使我告诉 spring 不要在
pubsub
上验证请求,如果它看到 authentication
标头,它会尝试验证和验证它。这从一开始就没有意义,我认为这是一个错误。
因此,为了使这项工作正常进行,您需要两个安全过滤器链,一个用于此端点,禁用安全性,另一个用于其余内容。当然,这些豆子的顺序非常重要。这个特定事物的过滤器链如下所示:
@Bean
@Order(-1)
public SecurityFilterChain filterChain1(HttpSecurity http) throws Exception {
http
.cors(AbstractHttpConfigurer::disable)
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests((auth) -> auth.requestMatchers("/pubsub").permitAll())
.securityMatchers((auth) -> auth.requestMatchers("/pubsub"));
return http.build();
}
我做了这个
order(-1)
,以便它首先适用。如果您创建第二个端点,则将保护其余端点的安全。
这里要注意的事情,真正让我困惑的是,即使在链内部,我有一个请求匹配器,Spring 也不明白如何将整个链与传入过滤器进行匹配,这就是为什么你需要告诉它哪些 URL被分配到哪个过滤器链。这是通过这条线完成的
.securityMatchers((auth) -> auth.requestMatchers("/pubsub"));
看到这一点,spring 将此过滤器链的范围限制为
/pubsub
并使用其他过滤器来保护其余端点。