Skip to content

Using micrometer-tracing-bridge-{} breaks OAuth2/JWT validation #13431

@singhbaljit

Description

@singhbaljit

Describe the bug

I'm using Spring Security (reactive, v6.1.1). Adding the micrometer-tracing-bridge-otel or micrometer-tracing-bridge-brave dependency breaks the OAuth2 resource server. I also have the Hooks.enableAutomaticContextPropagation() per this guide.

2023-06-26T22:59:19.199-04:00 ERROR 96867 --- [ctor-http-nio-3] reactor.core.publisher.Operators         : Operator called default onErrorDropped

java.lang.AssertionError: Observation <{name=spring.security.filterchains(security filterchain before), error=org.springframework.security.authentication.AuthenticationServiceException: An error occurred while attempting to decode the Jwt: , context=name='spring.security.filterchains', contextualName='security filterchain before', error='org.springframework.security.authentication.AuthenticationServiceException: An error occurred while attempting to decode the Jwt: ', lowCardinalityKeyValues=[spring.security.filterchain.position='4', spring.security.filterchain.size='9', spring.security.reached.filter.name='AuthenticationWebFilter', spring.security.reached.filter.section='before'], highCardinalityKeyValues=[], map=[class io.micrometer.core.instrument.LongTaskTimer$Sample='SampleImpl{duration(seconds)=-1.0E-9, duration(nanos)=-1.0, startTimeNanos=60545232013441}', class io.micrometer.core.instrument.Timer$Sample='io.micrometer.core.instrument.Timer$Sample@6af5a3e3'], parentObservation={name=http.server.requests(http delete), error=org.springframework.security.authentication.AuthenticationServiceException: An error occurred while attempting to decode the Jwt: , context=name='http.server.requests', contextualName='http delete', error='org.springframework.security.authentication.AuthenticationServiceException: An error occurred while attempting to decode the Jwt: ', lowCardinalityKeyValues=[exception='AuthenticationServiceException', method='DELETE', outcome='SERVER_ERROR', status='500', uri='UNKNOWN'], highCardinalityKeyValues=[http.url='/api/bad-request'], map=[class io.micrometer.core.instrument.LongTaskTimer$Sample='SampleImpl{duration(seconds)=-1.0E-9, duration(nanos)=-1.0, startTimeNanos=60545219139591}', class io.micrometer.core.instrument.Timer$Sample='io.micrometer.core.instrument.Timer$Sample@6f51d0ed'], parentObservation=null}}> to which we're restoring is not the same as the one set as this scope's parent observation <{name=http.server.requests(http delete), error=org.springframework.security.authentication.AuthenticationServiceException: An error occurred while attempting to decode the Jwt: , context=name='http.server.requests', contextualName='http delete', error='org.springframework.security.authentication.AuthenticationServiceException: An error occurred while attempting to decode the Jwt: ', lowCardinalityKeyValues=[exception='AuthenticationServiceException', method='DELETE', outcome='SERVER_ERROR', status='500', uri='UNKNOWN'], highCardinalityKeyValues=[http.url='/api/bad-request'], map=[class io.micrometer.core.instrument.LongTaskTimer$Sample='SampleImpl{duration(seconds)=-1.0E-9, duration(nanos)=-1.0, startTimeNanos=60545219139591}', class io.micrometer.core.instrument.Timer$Sample='io.micrometer.core.instrument.Timer$Sample@6f51d0ed'], parentObservation=null}> . Most likely a manually created Observation has a scope opened that was never closed. This may lead to thread polluting and memory leaks
	at io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor.restore(ObservationThreadLocalAccessor.java:148)
	at io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor.restore(ObservationThreadLocalAccessor.java:32)
	at io.micrometer.context.DefaultContextSnapshot$DefaultScope.resetThreadLocalValue(DefaultContextSnapshot.java:144)

To Reproduce

My security configuration:

@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
class AuthConfig {

  @Bean
  JwtIssuerReactiveAuthenticationManagerResolver authenticationManagerResolver(
      @Value("${auth.issuerUrl}") final String authIssuerUrl) {
    return new JwtIssuerReactiveAuthenticationManagerResolver(authIssuerUrl);
  }

  @Bean
  SecurityWebFilterChain securityWebFilterChain(
      final ServerHttpSecurity httpSecurity,
      final JwtIssuerReactiveAuthenticationManagerResolver authenticationManagerResolver) {

    httpSecurity.authorizeExchange(exchange -> exchange
        .anyExchange().authenticated());

    httpSecurity.oauth2ResourceServer(resourceServer -> resourceServer
        .authenticationManagerResolver(authenticationManagerResolver));

    return httpSecurity.build();
  }
}

Expected behavior

Using the tracing library should not break Spring Security.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions