|
@@ -33,9 +33,11 @@ import reactor.core.publisher.Flux;
|
|
import reactor.core.publisher.Mono;
|
|
import reactor.core.publisher.Mono;
|
|
import reactor.test.StepVerifier;
|
|
import reactor.test.StepVerifier;
|
|
|
|
|
|
|
|
+import org.springframework.beans.BeansException;
|
|
import org.springframework.beans.factory.ObjectProvider;
|
|
import org.springframework.beans.factory.ObjectProvider;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.config.BeanDefinition;
|
|
import org.springframework.beans.factory.config.BeanDefinition;
|
|
|
|
+import org.springframework.beans.factory.config.BeanPostProcessor;
|
|
import org.springframework.context.annotation.Bean;
|
|
import org.springframework.context.annotation.Bean;
|
|
import org.springframework.context.annotation.Configuration;
|
|
import org.springframework.context.annotation.Configuration;
|
|
import org.springframework.context.annotation.Role;
|
|
import org.springframework.context.annotation.Role;
|
|
@@ -55,6 +57,7 @@ import org.springframework.security.authorization.method.AuthorizeReturnObject;
|
|
import org.springframework.security.authorization.method.MethodAuthorizationDeniedHandler;
|
|
import org.springframework.security.authorization.method.MethodAuthorizationDeniedHandler;
|
|
import org.springframework.security.config.Customizer;
|
|
import org.springframework.security.config.Customizer;
|
|
import org.springframework.security.config.core.GrantedAuthorityDefaults;
|
|
import org.springframework.security.config.core.GrantedAuthorityDefaults;
|
|
|
|
+import org.springframework.security.config.observation.SecurityObservationSettings;
|
|
import org.springframework.security.config.test.SpringTestContext;
|
|
import org.springframework.security.config.test.SpringTestContext;
|
|
import org.springframework.security.config.test.SpringTestContextExtension;
|
|
import org.springframework.security.config.test.SpringTestContextExtension;
|
|
import org.springframework.security.core.Authentication;
|
|
import org.springframework.security.core.Authentication;
|
|
@@ -69,6 +72,7 @@ import static org.mockito.Mockito.mock;
|
|
import static org.mockito.Mockito.never;
|
|
import static org.mockito.Mockito.never;
|
|
import static org.mockito.Mockito.spy;
|
|
import static org.mockito.Mockito.spy;
|
|
import static org.mockito.Mockito.verify;
|
|
import static org.mockito.Mockito.verify;
|
|
|
|
+import static org.mockito.Mockito.verifyNoInteractions;
|
|
|
|
|
|
/**
|
|
/**
|
|
* @author Tadaya Tsuyukubo
|
|
* @author Tadaya Tsuyukubo
|
|
@@ -260,6 +264,27 @@ public class ReactiveMethodSecurityConfigurationTests {
|
|
verify(handler).onError(any());
|
|
verify(handler).onError(any());
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Test
|
|
|
|
+ @WithMockUser
|
|
|
|
+ public void prePostMethodWhenExcludeAuthorizationObservationsThenUnobserved() {
|
|
|
|
+ this.spring
|
|
|
|
+ .register(MethodSecurityServiceConfig.class, ObservationRegistryConfig.class,
|
|
|
|
+ SelectableObservationsConfig.class)
|
|
|
|
+ .autowire();
|
|
|
|
+ ReactiveMethodSecurityService service = this.spring.getContext().getBean(ReactiveMethodSecurityService.class);
|
|
|
|
+ Authentication user = TestAuthentication.authenticatedUser();
|
|
|
|
+ StepVerifier
|
|
|
|
+ .create(service.preAuthorizeUser().contextWrite(ReactiveSecurityContextHolder.withAuthentication(user)))
|
|
|
|
+ .expectNextCount(1)
|
|
|
|
+ .verifyComplete();
|
|
|
|
+ ObservationHandler<?> handler = this.spring.getContext().getBean(ObservationHandler.class);
|
|
|
|
+ StepVerifier
|
|
|
|
+ .create(service.preAuthorizeAdmin().contextWrite(ReactiveSecurityContextHolder.withAuthentication(user)))
|
|
|
|
+ .expectError()
|
|
|
|
+ .verify();
|
|
|
|
+ verifyNoInteractions(handler);
|
|
|
|
+ }
|
|
|
|
+
|
|
private static Consumer<User.UserBuilder> authorities(String... authorities) {
|
|
private static Consumer<User.UserBuilder> authorities(String... authorities) {
|
|
return (builder) -> builder.authorities(authorities);
|
|
return (builder) -> builder.authorities(authorities);
|
|
}
|
|
}
|
|
@@ -432,9 +457,37 @@ public class ReactiveMethodSecurityConfigurationTests {
|
|
}
|
|
}
|
|
|
|
|
|
@Bean
|
|
@Bean
|
|
- PrePostMethodSecurityConfigurationTests.ObservationRegistryPostProcessor observationRegistryPostProcessor(
|
|
|
|
|
|
+ ObservationRegistryPostProcessor observationRegistryPostProcessor(
|
|
ObjectProvider<ObservationHandler<Observation.Context>> handler) {
|
|
ObjectProvider<ObservationHandler<Observation.Context>> handler) {
|
|
- return new PrePostMethodSecurityConfigurationTests.ObservationRegistryPostProcessor(handler);
|
|
|
|
|
|
+ return new ObservationRegistryPostProcessor(handler);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ static class ObservationRegistryPostProcessor implements BeanPostProcessor {
|
|
|
|
+
|
|
|
|
+ private final ObjectProvider<ObservationHandler<Observation.Context>> handler;
|
|
|
|
+
|
|
|
|
+ ObservationRegistryPostProcessor(ObjectProvider<ObservationHandler<Observation.Context>> handler) {
|
|
|
|
+ this.handler = handler;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
|
|
|
+ if (bean instanceof ObservationRegistry registry) {
|
|
|
|
+ registry.observationConfig().observationHandler(this.handler.getObject());
|
|
|
|
+ }
|
|
|
|
+ return bean;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Configuration
|
|
|
|
+ static class SelectableObservationsConfig {
|
|
|
|
+
|
|
|
|
+ @Bean
|
|
|
|
+ SecurityObservationSettings observabilityDefaults() {
|
|
|
|
+ return SecurityObservationSettings.withDefaults().shouldObserveAuthorizations(false).build();
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|