|
28 | 28 | import java.util.function.Consumer;
|
29 | 29 | import java.util.function.Supplier;
|
30 | 30 |
|
| 31 | +import ch.qos.logback.classic.Level; |
| 32 | +import ch.qos.logback.classic.Logger; |
| 33 | +import ch.qos.logback.classic.spi.ILoggingEvent; |
| 34 | +import ch.qos.logback.core.read.ListAppender; |
31 | 35 | import io.micrometer.observation.Observation;
|
32 | 36 | import io.micrometer.observation.ObservationHandler;
|
33 | 37 | import io.micrometer.observation.ObservationRegistry;
|
|
40 | 44 | import org.junit.jupiter.api.extension.ExtendWith;
|
41 | 45 | import org.junit.jupiter.params.ParameterizedTest;
|
42 | 46 | import org.junit.jupiter.params.provider.ValueSource;
|
| 47 | +import org.slf4j.LoggerFactory; |
43 | 48 |
|
44 | 49 | import org.springframework.aop.Advisor;
|
45 | 50 | import org.springframework.aop.Pointcut;
|
|
125 | 130 | import org.springframework.test.web.servlet.MockMvc;
|
126 | 131 | import org.springframework.test.web.servlet.MvcResult;
|
127 | 132 | import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
| 133 | +import org.springframework.transaction.annotation.EnableTransactionManagement; |
128 | 134 | import org.springframework.web.bind.annotation.ControllerAdvice;
|
129 | 135 | import org.springframework.web.bind.annotation.ExceptionHandler;
|
130 | 136 | import org.springframework.web.bind.annotation.GetMapping;
|
|
156 | 162 | *
|
157 | 163 | * @author Evgeniy Cheban
|
158 | 164 | * @author Josh Cummings
|
| 165 | + * @author Yoobin Yoon |
159 | 166 | */
|
160 | 167 | @ExtendWith({ SpringExtension.class, SpringTestContextExtension.class })
|
161 | 168 | @ContextConfiguration(classes = SecurityContextChangedListenerConfig.class)
|
@@ -1348,6 +1355,85 @@ void getWhenCustomAdvisorAuthenticationNameNotMatchThenRespondsWithForbidden() t
|
1348 | 1355 | this.mvc.perform(requestWithUser).andExpect(status().isForbidden());
|
1349 | 1356 | }
|
1350 | 1357 |
|
| 1358 | + @Test |
| 1359 | + public void configureWhenTransactionManagementThenWarningCondition() { |
| 1360 | + this.spring.register(TransactionManagementConfig.class).autowire(); |
| 1361 | + assertThat(this.spring.getContext().getBean(MethodSecurityService.class)).isNotNull(); |
| 1362 | + EnableTransactionManagement txMgmt = TransactionManagementConfig.class |
| 1363 | + .getAnnotation(EnableTransactionManagement.class); |
| 1364 | + assertThat(txMgmt.order()).isGreaterThan(100); |
| 1365 | + } |
| 1366 | + |
| 1367 | + @Test |
| 1368 | + public void configureWhenTransactionManagementLowerPrecedenceThenWarningCondition() { |
| 1369 | + this.spring.register(TransactionManagementLowerPrecedenceConfig.class).autowire(); |
| 1370 | + EnableTransactionManagement txMgmt = TransactionManagementLowerPrecedenceConfig.class |
| 1371 | + .getAnnotation(EnableTransactionManagement.class); |
| 1372 | + assertThat(txMgmt.order()).isGreaterThan(100); |
| 1373 | + } |
| 1374 | + |
| 1375 | + @Test |
| 1376 | + public void configureWhenTransactionManagementHigherPrecedenceThenNoWarningCondition() { |
| 1377 | + this.spring.register(TransactionManagementHigherPrecedenceConfig.class).autowire(); |
| 1378 | + assertThat(this.spring.getContext().getBean(MethodSecurityService.class)).isNotNull(); |
| 1379 | + EnableTransactionManagement txMgmt = TransactionManagementHigherPrecedenceConfig.class |
| 1380 | + .getAnnotation(EnableTransactionManagement.class); |
| 1381 | + assertThat(txMgmt.order()).isLessThanOrEqualTo(100); |
| 1382 | + } |
| 1383 | + |
| 1384 | + @Test |
| 1385 | + public void configureWhenTransactionManagementSameOrderThenWarningCondition() { |
| 1386 | + this.spring.register(TransactionManagementSameOrderConfig.class).autowire(); |
| 1387 | + EnableTransactionManagement txMgmt = TransactionManagementSameOrderConfig.class |
| 1388 | + .getAnnotation(EnableTransactionManagement.class); |
| 1389 | + assertThat(txMgmt.order()).isEqualTo(100); |
| 1390 | + } |
| 1391 | + |
| 1392 | + @Test |
| 1393 | + public void configureWhenMethodSecurityOffsetThenWarningCondition() { |
| 1394 | + this.spring.register(MethodSecurityOffsetWithTransactionConfig.class).autowire(); |
| 1395 | + EnableMethodSecurity methodSecurity = MethodSecurityOffsetWithTransactionConfig.class |
| 1396 | + .getAnnotation(EnableMethodSecurity.class); |
| 1397 | + EnableTransactionManagement txMgmt = MethodSecurityOffsetWithTransactionConfig.class |
| 1398 | + .getAnnotation(EnableTransactionManagement.class); |
| 1399 | + int effectiveMethodSecurityOrder = 100 + methodSecurity.offset(); |
| 1400 | + assertThat(txMgmt.order()).isGreaterThan(effectiveMethodSecurityOrder); |
| 1401 | + } |
| 1402 | + |
| 1403 | + @Test |
| 1404 | + public void configureWhenTransactionManagementSameOrderThenNoWarningCondition() { |
| 1405 | + this.spring.register(TransactionManagementSameOrderConfig.class).autowire(); |
| 1406 | + EnableTransactionManagement txMgmt = TransactionManagementSameOrderConfig.class |
| 1407 | + .getAnnotation(EnableTransactionManagement.class); |
| 1408 | + assertThat(txMgmt.order()).isEqualTo(100); |
| 1409 | + } |
| 1410 | + |
| 1411 | + @Test |
| 1412 | + public void configureWhenTransactionManagementLowerPrecedenceThenValidationRuns() { |
| 1413 | + assertThatNoException() |
| 1414 | + .isThrownBy(() -> this.spring.register(TransactionManagementLowerPrecedenceConfig.class).autowire()); |
| 1415 | + assertThat(this.spring.getContext().getBean(MethodSecurityService.class)).isNotNull(); |
| 1416 | + } |
| 1417 | + |
| 1418 | + @Test |
| 1419 | + public void validateTransactionManagementPrecedenceWhenLowerPrecedenceThenLogsWarning() { |
| 1420 | + Logger logger = (Logger) LoggerFactory.getLogger(PrePostMethodSecurityConfiguration.class); |
| 1421 | + ListAppender<ILoggingEvent> appender = new ListAppender<>(); |
| 1422 | + appender.start(); |
| 1423 | + logger.addAppender(appender); |
| 1424 | + try { |
| 1425 | + this.spring.register(TransactionManagementLowerPrecedenceConfig.class).autowire(); |
| 1426 | + assertThat(appender.list).hasSize(1); |
| 1427 | + assertThat(appender.list.get(0).getLevel()).isEqualTo(Level.WARN); |
| 1428 | + assertThat(appender.list.get(0).getMessage()) |
| 1429 | + .contains("@EnableTransactionManagement has same or lower precedence"); |
| 1430 | + |
| 1431 | + } |
| 1432 | + finally { |
| 1433 | + logger.detachAppender(appender); |
| 1434 | + } |
| 1435 | + } |
| 1436 | + |
1351 | 1437 | private static Consumer<ConfigurableWebApplicationContext> disallowBeanOverriding() {
|
1352 | 1438 | return (context) -> ((AnnotationConfigWebApplicationContext) context).setAllowBeanDefinitionOverriding(false);
|
1353 | 1439 | }
|
@@ -2201,4 +2287,75 @@ public String getName() {
|
2201 | 2287 |
|
2202 | 2288 | }
|
2203 | 2289 |
|
| 2290 | + @Configuration |
| 2291 | + @EnableMethodSecurity(prePostEnabled = true) |
| 2292 | + @EnableTransactionManagement |
| 2293 | + static class TransactionManagementConfig { |
| 2294 | + |
| 2295 | + @Bean |
| 2296 | + MethodSecurityService methodSecurityService() { |
| 2297 | + return new MethodSecurityServiceImpl(); |
| 2298 | + } |
| 2299 | + |
| 2300 | + } |
| 2301 | + |
| 2302 | + @Configuration |
| 2303 | + @EnableMethodSecurity(prePostEnabled = true) |
| 2304 | + @EnableTransactionManagement(order = 300) |
| 2305 | + static class TransactionManagementLowerPrecedenceConfig { |
| 2306 | + |
| 2307 | + @Bean |
| 2308 | + MethodSecurityService methodSecurityService() { |
| 2309 | + return new MethodSecurityServiceImpl(); |
| 2310 | + } |
| 2311 | + |
| 2312 | + } |
| 2313 | + |
| 2314 | + @Configuration |
| 2315 | + @EnableMethodSecurity(prePostEnabled = true) |
| 2316 | + @EnableTransactionManagement(order = 0) |
| 2317 | + static class TransactionManagementHigherPrecedenceConfig { |
| 2318 | + |
| 2319 | + @Bean |
| 2320 | + MethodSecurityService methodSecurityService() { |
| 2321 | + return new MethodSecurityServiceImpl(); |
| 2322 | + } |
| 2323 | + |
| 2324 | + } |
| 2325 | + |
| 2326 | + @Configuration |
| 2327 | + @EnableMethodSecurity(prePostEnabled = true) |
| 2328 | + @EnableTransactionManagement(order = 100) |
| 2329 | + static class TransactionManagementSameOrderConfig { |
| 2330 | + |
| 2331 | + @Bean |
| 2332 | + MethodSecurityService methodSecurityService() { |
| 2333 | + return new MethodSecurityServiceImpl(); |
| 2334 | + } |
| 2335 | + |
| 2336 | + } |
| 2337 | + |
| 2338 | + @Configuration |
| 2339 | + @EnableMethodSecurity(prePostEnabled = true) |
| 2340 | + static class NoTransactionManagementConfig { |
| 2341 | + |
| 2342 | + @Bean |
| 2343 | + MethodSecurityService methodSecurityService() { |
| 2344 | + return new MethodSecurityServiceImpl(); |
| 2345 | + } |
| 2346 | + |
| 2347 | + } |
| 2348 | + |
| 2349 | + @Configuration |
| 2350 | + @EnableMethodSecurity(prePostEnabled = true, offset = 50) |
| 2351 | + @EnableTransactionManagement(order = 200) |
| 2352 | + static class MethodSecurityOffsetWithTransactionConfig { |
| 2353 | + |
| 2354 | + @Bean |
| 2355 | + MethodSecurityService methodSecurityService() { |
| 2356 | + return new MethodSecurityServiceImpl(); |
| 2357 | + } |
| 2358 | + |
| 2359 | + } |
| 2360 | + |
2204 | 2361 | }
|
0 commit comments