【发布时间】:2021-04-21 11:55:15
【问题描述】:
我正在将微服务配置为资源服务器,它使用 JWK 端点来验证 JWT 令牌的签名。
我已将配置设置为允许服务中的所有GET 请求。所有其他请求都根据范围和角色进行保护。这是我正在使用的配置。
@EnableReactiveMethodSecurity
class SecurityConfig : WebFluxConfigurer {
@Bean
fun authenticationEntryPoint(): ServerAuthenticationEntryPoint {
return JwtBearerTokenServerAuthenticationEntryPoint()
}
@Bean
fun accessDeniedHandler(): ServerAccessDeniedHandler {
return JwtTokenAccessDeniedHandler()
}
@Bean
fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
http
.authorizeExchange()
.pathMatchers(HttpMethod.GET).permitAll()
.pathMatchers("/docs/**", "/v2/api-docs/**", "/").permitAll()
// Client should have the required scope to write to products
.pathMatchers(HttpMethod.POST).hasAuthority(PRODUCT_WRITE_SCOPE)
.pathMatchers(HttpMethod.PUT).hasAuthority(PRODUCT_WRITE_SCOPE)
.pathMatchers(HttpMethod.DELETE).hasAuthority(PRODUCT_WRITE_SCOPE)
// health and info urls will be open(permitted to all) others will be checked for authorization
.matchers(EndpointRequest.to(HealthEndpoint::class.java, InfoEndpoint::class.java)).permitAll()
.anyExchange().authenticated()
.and()
.csrf().disable()
.formLogin().disable()
.oauth2ResourceServer()
.authenticationEntryPoint(authenticationEntryPoint())
.accessDeniedHandler(accessDeniedHandler())
.jwt()
.jwtAuthenticationConverter {
jwtAuthenticationConverter(it)
}
return http.build()
}
private fun jwtAuthenticationConverter(jwt: Jwt): Mono<AbstractAuthenticationToken>? {
val jwtAuthConverter = ReactiveJwtAuthenticationConverter()
jwtAuthConverter.setJwtGrantedAuthoritiesConverter {
val jwtGrantedAuthoritiesConverter = JwtAuthoritiesConverter()
val reactiveJwtGrantedAuthoritiesConverterAdapter =
ReactiveJwtGrantedAuthoritiesConverterAdapter(jwtGrantedAuthoritiesConverter)
reactiveJwtGrantedAuthoritiesConverterAdapter.convert(it)
}
return jwtAuthConverter.convert(jwt)
}
companion object {
private const val PRODUCT_WRITE_SCOPE = "SCOPE_product:write"
}
}
我面临的问题是,如果我在 GET 请求的授权标头中发送过期令牌,令牌验证仍然会发生并且我收到令牌过期错误。
有没有办法改变配置,使令牌验证只发生在某些端点上,而忽略其他端点?
【问题讨论】:
-
为什么不在所有 get 请求中发送授权标头?
-
我在所有请求中发送授权标头。这就是问题出现的地方。如果令牌已过期,则 GET 请求失败,说明令牌已过期。
-
是的,我确实理解您的问题,但正如我所说,当您不想获得授权时,更好的解决方案是不发送令牌。
-
@Toerktumlare 这当然是一个选项,但我认为它可能会在客户端实现中添加更多条件检查,因此希望避免这种情况。如果没有办法做到这一点,那就是我会去的。
-
从语义上考虑,如果您发送
Authorization标头,您是在告诉后端“嗨,这是我的请求,这是证明我是谁的标头”。现在您想发送一个身份验证标头,即使您不想要或不应该,而是忽略它?对我来说,这听起来像是给自己制造更多问题。我在春天看不到任何明显的东西可以让你做到这一点,而且很确定春天同意我的看法。如果您不想被授权,请不要发送授权标头。
标签: java spring-security jwt spring-webflux spring-security-oauth2