Skip to content

Commit

Permalink
Make ObservationConventions Globally Configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
jzheaux committed Sep 23, 2024
1 parent 800f48a commit 48eeb11
Show file tree
Hide file tree
Showing 15 changed files with 541 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.springframework.security.authorization.method.MethodInvocationResult;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.observation.AbstractObservationObjectPostProcessor;
import org.springframework.security.config.observation.ObservationObjectPostProcessor;

@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
Expand All @@ -37,27 +38,40 @@ class MethodObservationConfiguration {
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static ObjectPostProcessor<AuthorizationManager<MethodInvocation>> methodAuthorizationManagerPostProcessor(
ObjectProvider<ObservationRegistry> registry) {
return new AbstractObservationObjectPostProcessor<>(registry) {
@Override
protected <O extends AuthorizationManager<MethodInvocation>> O postProcess(ObservationRegistry registry,
O object) {
return (O) new ObservationAuthorizationManager<>(registry, object);
}
ObjectProvider<ObservationRegistry> registry,
ObjectProvider<ObservationObjectPostProcessor<AuthorizationManager<MethodInvocation>>> postProcessor) {
return new AbstractMethodSecurityObservationObjectPostProcessor<>(registry, postProcessor) {

};
}

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static ObjectPostProcessor<AuthorizationManager<MethodInvocationResult>> methodResultAuthorizationManagerPostProcessor(
ObjectProvider<ObservationRegistry> registry) {
return new AbstractObservationObjectPostProcessor<>(registry) {
@Override
protected <O extends AuthorizationManager<MethodInvocationResult>> O postProcess(
ObservationRegistry registry, O object) {
return (O) new ObservationAuthorizationManager<>(registry, object);
}
ObjectProvider<ObservationRegistry> registry,
ObjectProvider<ObservationObjectPostProcessor<AuthorizationManager<MethodInvocationResult>>> postProcessor) {
return new AbstractMethodSecurityObservationObjectPostProcessor<>(registry, postProcessor) {

};
}

private static class AbstractMethodSecurityObservationObjectPostProcessor<T>
extends AbstractObservationObjectPostProcessor<AuthorizationManager<T>> {

ObjectProvider<ObservationObjectPostProcessor<AuthorizationManager<T>>> postProcessor;

AbstractMethodSecurityObservationObjectPostProcessor(ObjectProvider<ObservationRegistry> registry,
ObjectProvider<ObservationObjectPostProcessor<AuthorizationManager<T>>> postProcessor) {
super(registry);
this.postProcessor = postProcessor;
}

@Override
protected <O extends AuthorizationManager<T>> O postProcess(ObservationRegistry registry, O object) {
return (O) this.postProcessor.getIfUnique(() -> ObservationAuthorizationManager::new)
.postProcess(registry, object);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.springframework.security.authorization.method.MethodInvocationResult;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.observation.AbstractObservationObjectPostProcessor;
import org.springframework.security.config.observation.ObservationObjectPostProcessor;

@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
Expand All @@ -37,27 +38,40 @@ class ReactiveMethodObservationConfiguration {
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static ObjectPostProcessor<ReactiveAuthorizationManager<MethodInvocation>> methodAuthorizationManagerPostProcessor(
ObjectProvider<ObservationRegistry> registry) {
return new AbstractObservationObjectPostProcessor<>(registry) {
@Override
protected <O extends ReactiveAuthorizationManager<MethodInvocation>> O postProcess(
ObservationRegistry registry, O object) {
return (O) new ObservationReactiveAuthorizationManager<>(registry, object);
}
ObjectProvider<ObservationRegistry> registry,
ObjectProvider<ObservationObjectPostProcessor<ReactiveAuthorizationManager<MethodInvocation>>> postProcessor) {
return new AbstractMethodSecurityObservationObjectPostProcessor<>(registry, postProcessor) {

};
}

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
ObjectPostProcessor<ReactiveAuthorizationManager<MethodInvocationResult>> methodResultAuthorizationManagerPostProcessor(
ObjectProvider<ObservationRegistry> registry) {
return new AbstractObservationObjectPostProcessor<>(registry) {
@Override
protected <O extends ReactiveAuthorizationManager<MethodInvocationResult>> O postProcess(
ObservationRegistry registry, O object) {
return (O) new ObservationReactiveAuthorizationManager<>(registry, object);
}
ObjectProvider<ObservationRegistry> registry,
ObjectProvider<ObservationObjectPostProcessor<ReactiveAuthorizationManager<MethodInvocationResult>>> postProcessor) {
return new AbstractMethodSecurityObservationObjectPostProcessor<>(registry, postProcessor) {

};
}

private static class AbstractMethodSecurityObservationObjectPostProcessor<T>
extends AbstractObservationObjectPostProcessor<ReactiveAuthorizationManager<T>> {

ObjectProvider<ObservationObjectPostProcessor<ReactiveAuthorizationManager<T>>> postProcessor;

AbstractMethodSecurityObservationObjectPostProcessor(ObjectProvider<ObservationRegistry> registry,
ObjectProvider<ObservationObjectPostProcessor<ReactiveAuthorizationManager<T>>> postProcessor) {
super(registry);
this.postProcessor = postProcessor;
}

@Override
protected <O extends ReactiveAuthorizationManager<T>> O postProcess(ObservationRegistry registry, O object) {
return (O) this.postProcessor.getIfUnique(() -> ObservationReactiveAuthorizationManager::new)
.postProcess(registry, object);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public String[] selectImports(AnnotationMetadata importMetadata) {
imports.add(AuthorizationProxyDataConfiguration.class.getName());
}
if (isObservabilityPresent) {
imports.add(ReactiveMethodSecurityConfiguration.class.getName());
imports.add(ReactiveMethodObservationConfiguration.class.getName());
}
imports.add(AuthorizationProxyConfiguration.class.getName());
return imports.toArray(new String[0]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.springframework.security.authorization.ReactiveAuthorizationManager;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.observation.AbstractObservationObjectPostProcessor;
import org.springframework.security.config.observation.ObservationObjectPostProcessor;
import org.springframework.security.web.server.ObservationWebFilterChainDecorator;
import org.springframework.security.web.server.WebFilterChainProxy.WebFilterChainDecorator;
import org.springframework.web.server.ServerWebExchange;
Expand All @@ -40,36 +41,42 @@ class ReactiveObservationConfiguration {
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static ObjectPostProcessor<ReactiveAuthorizationManager<ServerWebExchange>> webAuthorizationManagerPostProcessor(
ObjectProvider<ObservationRegistry> registry) {
ObjectProvider<ObservationRegistry> registry,
ObjectProvider<ObservationObjectPostProcessor<ReactiveAuthorizationManager<ServerWebExchange>>> postProcessor) {
return new AbstractObservationObjectPostProcessor<>(registry) {
@Override
protected <O extends ReactiveAuthorizationManager<ServerWebExchange>> O postProcess(
ObservationRegistry registry, O object) {
return (O) new ObservationReactiveAuthorizationManager(registry, object);
return (O) postProcessor.getIfUnique(() -> ObservationReactiveAuthorizationManager::new)
.postProcess(registry, object);
}
};
}

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static ObjectPostProcessor<ReactiveAuthenticationManager> authenticationManagerPostProcessor(
ObjectProvider<ObservationRegistry> registry) {
ObjectProvider<ObservationRegistry> registry,
ObjectProvider<ObservationObjectPostProcessor<ReactiveAuthenticationManager>> postProcessor) {
return new AbstractObservationObjectPostProcessor<>(registry) {
@Override
protected <O extends ReactiveAuthenticationManager> O postProcess(ObservationRegistry registry, O object) {
return (O) new ObservationReactiveAuthenticationManager(registry, object);
return (O) postProcessor.getIfUnique(() -> ObservationReactiveAuthenticationManager::new)
.postProcess(registry, object);
}
};
}

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static ObjectPostProcessor<WebFilterChainDecorator> filterChainDecoratorPostProcessor(
ObjectProvider<ObservationRegistry> registry) {
ObjectProvider<ObservationRegistry> registry,
ObjectProvider<ObservationObjectPostProcessor<WebFilterChainDecorator>> postProcessor) {
return new AbstractObservationObjectPostProcessor<>(registry) {
@Override
protected <O extends WebFilterChainDecorator> O postProcess(ObservationRegistry registry, O object) {
return (O) new ObservationWebFilterChainDecorator(registry);
return (O) postProcessor.getIfUnique(() -> (r, o) -> new ObservationWebFilterChainDecorator(r))
.postProcess(registry, object);
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.springframework.security.authorization.ObservationAuthorizationManager;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.observation.AbstractObservationObjectPostProcessor;
import org.springframework.security.config.observation.ObservationObjectPostProcessor;
import org.springframework.security.web.FilterChainProxy.FilterChainDecorator;
import org.springframework.security.web.ObservationFilterChainDecorator;

Expand All @@ -40,36 +41,42 @@ class ObservationConfiguration {
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static ObjectPostProcessor<AuthorizationManager<HttpServletRequest>> webAuthorizationManagerPostProcessor(
ObjectProvider<ObservationRegistry> registry) {
ObjectProvider<ObservationRegistry> registry,
ObjectProvider<ObservationObjectPostProcessor<AuthorizationManager<HttpServletRequest>>> postProcessor) {
return new AbstractObservationObjectPostProcessor<>(registry) {
@Override
protected <O extends AuthorizationManager<HttpServletRequest>> O postProcess(ObservationRegistry registry,
O object) {
return (O) new ObservationAuthorizationManager<>(registry, object);
return (O) postProcessor.getIfUnique(() -> ObservationAuthorizationManager::new)
.postProcess(registry, object);
}
};
}

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static ObjectPostProcessor<AuthenticationManager> authenticationManagerPostProcessor(
ObjectProvider<ObservationRegistry> registry) {
ObjectProvider<ObservationRegistry> registry,
ObjectProvider<ObservationObjectPostProcessor<AuthenticationManager>> postProcessor) {
return new AbstractObservationObjectPostProcessor<>(registry) {
@Override
protected AuthenticationManager postProcess(ObservationRegistry registry, AuthenticationManager object) {
return new ObservationAuthenticationManager(registry, object);
return postProcessor.getIfUnique(() -> ObservationAuthenticationManager::new)
.postProcess(registry, object);
}
};
}

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static ObjectPostProcessor<FilterChainDecorator> filterChainDecoratorPostProcessor(
ObjectProvider<ObservationRegistry> registry) {
ObjectProvider<ObservationRegistry> registry,
ObjectProvider<ObservationObjectPostProcessor<FilterChainDecorator>> postProcessor) {
return new AbstractObservationObjectPostProcessor<>(registry) {
@Override
protected FilterChainDecorator postProcess(ObservationRegistry registry, FilterChainDecorator object) {
return new ObservationFilterChainDecorator(registry);
return postProcessor.getIfUnique(() -> (r, o) -> new ObservationFilterChainDecorator(r))
.postProcess(registry, object);
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.springframework.security.authorization.ReactiveAuthorizationManager;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.observation.AbstractObservationObjectPostProcessor;
import org.springframework.security.config.observation.ObservationObjectPostProcessor;
import org.springframework.security.web.server.ObservationWebFilterChainDecorator;
import org.springframework.security.web.server.WebFilterChainProxy.WebFilterChainDecorator;
import org.springframework.web.server.ServerWebExchange;
Expand All @@ -40,36 +41,42 @@ class ReactiveObservationConfiguration {
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static ObjectPostProcessor<ReactiveAuthorizationManager<ServerWebExchange>> webAuthorizationManagerPostProcessor(
ObjectProvider<ObservationRegistry> registry) {
ObjectProvider<ObservationRegistry> registry,
ObjectProvider<ObservationObjectPostProcessor<ReactiveAuthorizationManager<ServerWebExchange>>> postProcessor) {
return new AbstractObservationObjectPostProcessor<>(registry) {
@Override
protected <O extends ReactiveAuthorizationManager<ServerWebExchange>> O postProcess(
ObservationRegistry registry, O object) {
return (O) new ObservationReactiveAuthorizationManager(registry, object);
return (O) postProcessor.getIfUnique(() -> ObservationReactiveAuthorizationManager::new)
.postProcess(registry, object);
}
};
}

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static ObjectPostProcessor<ReactiveAuthenticationManager> authenticationManagerPostProcessor(
ObjectProvider<ObservationRegistry> registry) {
ObjectProvider<ObservationRegistry> registry,
ObjectProvider<ObservationObjectPostProcessor<ReactiveAuthenticationManager>> postProcessor) {
return new AbstractObservationObjectPostProcessor<>(registry) {
@Override
protected <O extends ReactiveAuthenticationManager> O postProcess(ObservationRegistry registry, O object) {
return (O) new ObservationReactiveAuthenticationManager(registry, object);
return (O) postProcessor.getIfUnique(() -> ObservationReactiveAuthenticationManager::new)
.postProcess(registry, object);
}
};
}

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static ObjectPostProcessor<WebFilterChainDecorator> filterChainDecoratorPostProcessor(
ObjectProvider<ObservationRegistry> registry) {
ObjectProvider<ObservationRegistry> registry,
ObjectProvider<ObservationObjectPostProcessor<WebFilterChainDecorator>> postProcessor) {
return new AbstractObservationObjectPostProcessor<>(registry) {
@Override
protected <O extends WebFilterChainDecorator> O postProcess(ObservationRegistry registry, O object) {
return (O) new ObservationWebFilterChainDecorator(registry);
return (O) postProcessor.getIfUnique(() -> (r, o) -> new ObservationWebFilterChainDecorator(r))
.postProcess(registry, object);
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.springframework.security.authorization.ObservationAuthorizationManager;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.observation.AbstractObservationObjectPostProcessor;
import org.springframework.security.config.observation.ObservationObjectPostProcessor;

@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
Expand All @@ -36,12 +37,14 @@ class WebSocketObservationConfiguration {
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static ObjectPostProcessor<AuthorizationManager<Message<?>>> messageAuthorizationManagerPostProcessor(
ObjectProvider<ObservationRegistry> registry) {
ObjectProvider<ObservationRegistry> registry,
ObjectProvider<ObservationObjectPostProcessor<AuthorizationManager<Message<?>>>> postProcessor) {
return new AbstractObservationObjectPostProcessor<>(registry) {
@Override
protected <O extends AuthorizationManager<Message<?>>> O postProcess(ObservationRegistry registry,
O object) {
return (O) new ObservationAuthorizationManager<>(registry, object);
return (O) postProcessor.getIfUnique(() -> ObservationAuthorizationManager::new)
.postProcess(registry, object);
}
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.security.config.observation;

import io.micrometer.observation.ObservationRegistry;

public interface ObservationObjectPostProcessor<T> {

static <S> ObservationObjectPostProcessor<S> noop() {
return new ObservationObjectPostProcessor<>() {
@Override
public S postProcess(ObservationRegistry registry, S object) {
return object;
}
};
}

T postProcess(ObservationRegistry registry, T object);

}
Loading

0 comments on commit 48eeb11

Please sign in to comment.