我正在将微服务配置为使用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
请求的授权标头中发送了过期的令牌,令牌验证仍然会发生,并且我会收到令牌过期的错误。
有没有办法以仅在某些端点进行令牌验证而在其他端点忽略令牌验证的方式更改配置?
这是我为解决问题所做的工作。您可以选择指定安全配置应应用到的路径。这是指定代码段的代码段。
.securityMatcher {
ServerWebExchangeMatchers.matchers(
ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, "/**"),
ServerWebExchangeMatchers.pathMatchers(HttpMethod.PUT, "/**"),
ServerWebExchangeMatchers.pathMatchers(HttpMethod.DELETE, "/**")
).matches(it)
}
这是完整的配置。
@EnableReactiveMethodSecurity
class SecurityConfig : WebFluxConfigurer {
@Bean
fun authenticationEntryPoint(): ServerAuthenticationEntryPoint {
return JwtBearerTokenServerAuthenticationEntryPoint()
}
@Bean
fun accessDeniedHandler(): ServerAccessDeniedHandler {
return JwtTokenAccessDeniedHandler()
}
@Bean
fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
http
.securityMatcher {
ServerWebExchangeMatchers.matchers(
ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, "/**"),
ServerWebExchangeMatchers.pathMatchers(HttpMethod.PUT, "/**"),
ServerWebExchangeMatchers.pathMatchers(HttpMethod.DELETE, "/**")
).matches(it)
}
.authorizeExchange()
.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"
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句