mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-07-04 17:52:15 +00:00
Lookup Parent Observation
Closes gh-12524
This commit is contained in:
parent
21ceb333a8
commit
4d2dab9b6b
@ -18,6 +18,7 @@ package org.springframework.security.authentication;
|
|||||||
|
|
||||||
import io.micrometer.observation.Observation;
|
import io.micrometer.observation.Observation;
|
||||||
import io.micrometer.observation.ObservationRegistry;
|
import io.micrometer.observation.ObservationRegistry;
|
||||||
|
import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
@ -48,13 +49,16 @@ public class ObservationReactiveAuthenticationManager implements ReactiveAuthent
|
|||||||
AuthenticationObservationContext context = new AuthenticationObservationContext();
|
AuthenticationObservationContext context = new AuthenticationObservationContext();
|
||||||
context.setAuthenticationRequest(authentication);
|
context.setAuthenticationRequest(authentication);
|
||||||
context.setAuthenticationManagerClass(this.delegate.getClass());
|
context.setAuthenticationManagerClass(this.delegate.getClass());
|
||||||
Observation observation = Observation.createNotStarted(this.convention, () -> context, this.registry).start();
|
return Mono.deferContextual((contextView) -> {
|
||||||
return this.delegate.authenticate(authentication).doOnSuccess((result) -> {
|
Observation observation = Observation.createNotStarted(this.convention, () -> context, this.registry)
|
||||||
context.setAuthenticationResult(result);
|
.parentObservation(contextView.getOrDefault(ObservationThreadLocalAccessor.KEY, null)).start();
|
||||||
observation.stop();
|
return this.delegate.authenticate(authentication).doOnSuccess((result) -> {
|
||||||
}).doOnCancel(observation::stop).doOnError((t) -> {
|
context.setAuthenticationResult(result);
|
||||||
observation.error(t);
|
observation.stop();
|
||||||
observation.stop();
|
}).doOnCancel(observation::stop).doOnError((t) -> {
|
||||||
|
observation.error(t);
|
||||||
|
observation.stop();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ package org.springframework.security.authorization;
|
|||||||
|
|
||||||
import io.micrometer.observation.Observation;
|
import io.micrometer.observation.Observation;
|
||||||
import io.micrometer.observation.ObservationRegistry;
|
import io.micrometer.observation.ObservationRegistry;
|
||||||
|
import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import org.springframework.security.access.AccessDeniedException;
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
@ -50,16 +51,19 @@ public final class ObservationReactiveAuthorizationManager<T> implements Reactiv
|
|||||||
context.setAuthentication(auth);
|
context.setAuthentication(auth);
|
||||||
return context.getAuthentication();
|
return context.getAuthentication();
|
||||||
});
|
});
|
||||||
Observation observation = Observation.createNotStarted(this.convention, () -> context, this.registry).start();
|
return Mono.deferContextual((contextView) -> {
|
||||||
return this.delegate.check(wrapped, object).doOnSuccess((decision) -> {
|
Observation observation = Observation.createNotStarted(this.convention, () -> context, this.registry)
|
||||||
context.setDecision(decision);
|
.parentObservation(contextView.getOrDefault(ObservationThreadLocalAccessor.KEY, null)).start();
|
||||||
if (decision == null || !decision.isGranted()) {
|
return this.delegate.check(wrapped, object).doOnSuccess((decision) -> {
|
||||||
observation.error(new AccessDeniedException("Access Denied"));
|
context.setDecision(decision);
|
||||||
}
|
if (decision == null || !decision.isGranted()) {
|
||||||
observation.stop();
|
observation.error(new AccessDeniedException("Access Denied"));
|
||||||
}).doOnCancel(observation::stop).doOnError((t) -> {
|
}
|
||||||
observation.error(t);
|
observation.stop();
|
||||||
observation.stop();
|
}).doOnCancel(observation::stop).doOnError((t) -> {
|
||||||
|
observation.error(t);
|
||||||
|
observation.stop();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ import io.micrometer.common.KeyValues;
|
|||||||
import io.micrometer.observation.Observation;
|
import io.micrometer.observation.Observation;
|
||||||
import io.micrometer.observation.ObservationConvention;
|
import io.micrometer.observation.ObservationConvention;
|
||||||
import io.micrometer.observation.ObservationRegistry;
|
import io.micrometer.observation.ObservationRegistry;
|
||||||
|
import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
@ -73,20 +74,22 @@ public final class ObservationWebFilterChainDecorator implements WebFilterChainP
|
|||||||
}
|
}
|
||||||
|
|
||||||
private WebFilterChain wrapSecured(WebFilterChain original) {
|
private WebFilterChain wrapSecured(WebFilterChain original) {
|
||||||
return (exchange) -> {
|
return (exchange) -> Mono.deferContextual((contextView) -> {
|
||||||
AroundWebFilterObservation parent = observation(exchange);
|
AroundWebFilterObservation parent = observation(exchange);
|
||||||
|
Observation parentObservation = contextView.getOrDefault(ObservationThreadLocalAccessor.KEY, null);
|
||||||
Observation observation = Observation.createNotStarted(SECURED_OBSERVATION_NAME, this.registry)
|
Observation observation = Observation.createNotStarted(SECURED_OBSERVATION_NAME, this.registry)
|
||||||
.contextualName("secured request");
|
.contextualName("secured request").parentObservation(parentObservation);
|
||||||
return parent.wrap(WebFilterObservation.create(observation).wrap(original)).filter(exchange);
|
return parent.wrap(WebFilterObservation.create(observation).wrap(original)).filter(exchange);
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private WebFilterChain wrapUnsecured(WebFilterChain original) {
|
private WebFilterChain wrapUnsecured(WebFilterChain original) {
|
||||||
return (exchange) -> {
|
return (exchange) -> Mono.deferContextual((contextView) -> {
|
||||||
|
Observation parentObservation = contextView.getOrDefault(ObservationThreadLocalAccessor.KEY, null);
|
||||||
Observation observation = Observation.createNotStarted(UNSECURED_OBSERVATION_NAME, this.registry)
|
Observation observation = Observation.createNotStarted(UNSECURED_OBSERVATION_NAME, this.registry)
|
||||||
.contextualName("unsecured request");
|
.contextualName("unsecured request").parentObservation(parentObservation);
|
||||||
return WebFilterObservation.create(observation).wrap(original).filter(exchange);
|
return WebFilterObservation.create(observation).wrap(original).filter(exchange);
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ObservationWebFilter> wrap(List<WebFilter> filters) {
|
private List<ObservationWebFilter> wrap(List<WebFilter> filters) {
|
||||||
@ -186,8 +189,11 @@ public final class ObservationWebFilterChainDecorator implements WebFilterChainP
|
|||||||
@Override
|
@Override
|
||||||
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
||||||
if (this.position == 1) {
|
if (this.position == 1) {
|
||||||
AroundWebFilterObservation parent = parent(exchange);
|
return Mono.deferContextual((contextView) -> {
|
||||||
return parent.wrap(this::wrapFilter).filter(exchange, chain);
|
Observation parentObservation = contextView.getOrDefault(ObservationThreadLocalAccessor.KEY, null);
|
||||||
|
AroundWebFilterObservation parent = parent(exchange, parentObservation);
|
||||||
|
return parent.wrap(this::wrapFilter).filter(exchange, chain);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return wrapFilter(exchange, chain);
|
return wrapFilter(exchange, chain);
|
||||||
@ -211,11 +217,13 @@ public final class ObservationWebFilterChainDecorator implements WebFilterChainP
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private AroundWebFilterObservation parent(ServerWebExchange exchange) {
|
private AroundWebFilterObservation parent(ServerWebExchange exchange, Observation parentObservation) {
|
||||||
WebFilterChainObservationContext beforeContext = WebFilterChainObservationContext.before();
|
WebFilterChainObservationContext beforeContext = WebFilterChainObservationContext.before();
|
||||||
WebFilterChainObservationContext afterContext = WebFilterChainObservationContext.after();
|
WebFilterChainObservationContext afterContext = WebFilterChainObservationContext.after();
|
||||||
Observation before = Observation.createNotStarted(this.convention, () -> beforeContext, this.registry);
|
Observation before = Observation.createNotStarted(this.convention, () -> beforeContext, this.registry)
|
||||||
Observation after = Observation.createNotStarted(this.convention, () -> afterContext, this.registry);
|
.parentObservation(parentObservation);
|
||||||
|
Observation after = Observation.createNotStarted(this.convention, () -> afterContext, this.registry)
|
||||||
|
.parentObservation(parentObservation);
|
||||||
AroundWebFilterObservation parent = AroundWebFilterObservation.create(before, after);
|
AroundWebFilterObservation parent = AroundWebFilterObservation.create(before, after);
|
||||||
exchange.getAttributes().put(ATTRIBUTE, parent);
|
exchange.getAttributes().put(ATTRIBUTE, parent);
|
||||||
return parent;
|
return parent;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user