From d2ed5b401c36f446e5f0280b6019be2980c373bc Mon Sep 17 00:00:00 2001 From: David Turanski Date: Mon, 12 Jul 2021 19:37:23 -0400 Subject: [PATCH] Update security config for boot 2.5 (#177) * Add stream-application-integration-tests * Fix HttpRequestProcessorTests * Update security configuration to permit anonymous access to info and bindings * Update README --- .../README.adoc | 17 +++++++---- ...arterWebFluxSecurityAutoConfiguration.java | 16 +++++++--- ...ppStarterWebSecurityAutoConfiguration.java | 22 +++++++------- .../common/OnHttpCsrfOrSecurityDisabled.java | 4 +-- ...isabledManagementSecurityEnabledTests.java | 12 +++++++- ...SecurityEnabledAuthorizedAccessTests.java} | 30 ++++++++++++++----- ...curityDisabledUnauthorizedAccessTests.java | 15 ++++++++-- ...EnabledManagementSecurityEnabledTests.java | 15 ++++++++-- ...isabledManagementSecurityEnabledTests.java | 11 ++++++- ...SecurityEnabledAuthorizedAccessTests.java} | 18 +++++++---- ...curityDisabledUnauthorizedAccessTests.java | 10 ++++++- ...EnabledManagementSecurityEnabledTests.java | 2 +- .../source/time/KafkaTimeSourceTests.java | 1 - stream-applications-build/pom.xml | 1 - 14 files changed, 125 insertions(+), 49 deletions(-) rename applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/{ReactiveSecurityEnabledManagementSecurityDisabledAuthorizedAccessTests.java => ReactiveSecurityEnabledAuthorizedAccessTests.java} (76%) rename applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/{SecurityEnabledManagementSecurityDisabledAuthorizedAccessTests.java => SecurityEnabledAuthorizedAccessTests.java} (84%) diff --git a/applications/stream-applications-core/stream-applications-security-common/README.adoc b/applications/stream-applications-core/stream-applications-security-common/README.adoc index d87c31cf..15cb6d79 100644 --- a/applications/stream-applications-core/stream-applications-security-common/README.adoc +++ b/applications/stream-applications-core/stream-applications-security-common/README.adoc @@ -1,22 +1,27 @@ === `App Starters Security` Common Module -Spring Boot auto-configuration to manage the web security of the application starters. +Spring Boot auto-configuration to manage the web security of the pre-packaged stream applications. When the `app-starters-security-common` dependency is on the classpath, the `spring.cloud.streamapp.security.enabled` and `spring.cloud.streamapp.security.csrf-enabled` properties control the application security behavior. -By default the security is enabled allowing unauthorized access only to the `Info` and `Health` endpoints. +By default the security is enabled allowing unauthorized access only to the `actuator/info`,`actuator/health`, and `actuator/bindings` endpoints. The `spring.cloud.streamapp.security.enabled = false` completely surpass the application security. For secured application setting `spring.cloud.streamapp.security.csrf-enabled = false` disables security for the CSRF access. -With security enabled (`spring.cloud.streamapp.security.enabled = true`) and `actuator` dependency on the classpath, the `(Reactive)ManagementWebSecurityAutoConfiguration` is activated, providing unauthenticated access to the `HealthEndpoint` and `InfoEndpoint`. +With security enabled (`spring.cloud.streamapp.security.enabled = true`) and `actuator` dependency on the classpath, the `(Reactive)ManagementWebSecurityAutoConfiguration` is activated, providing unauthenticated access to the endpoints listed above. -If the user specifies their own `WebSecurityConfigurerAdapter` (for MVC application), this configuration will back-off completely and the user should specify all the bits that they want to configure as part of the custom security configuration. +If the user specifies their own `WebSecurityConfigurerAdapter` (for MVC application), this configuration will be overridden. The user must provide the complete security configuration. For reactive (WebFlux) application the same effect can be achieved with a custom `WebFilterChainProxy` bean. +[NOTE] +As of Spring Boot 2.5, the `info` endpoint requires authentication by default in `spring-boot-starter-security`. +Since, the contents of the `info` endpoint is highly customizable, the boot team has decided that an `opt-in` approach is more prudent. +For backward compatibility, the stream apps continue to expose the `info` endpoint. The standard configuration contains no sensitive information. + === Configuration -To include app starters security management for a stream app, just include a dependency on this module. +To include security management for a stream app, just include a dependency on this module. [source,xml] ---- @@ -27,7 +32,7 @@ To include app starters security management for a stream app, just include a dep ---- -All Spring Cloud Stream app starters that inherit form the `core` pom have the `app-starters-security-common` dependency included by default. +All Spring Cloud Stream applications that inherit form the `core` pom include the `stream-applications-security-common` dependency. * `spring.cloud.streamapp.security.enabled` (default: `true`). If set to `false` it surpasses the boot security. * `spring.cloud.streamapp.security.csrf-enabled` (default: `true`). If set to `false`, for secured applications it enables CQRS. diff --git a/applications/stream-applications-core/stream-applications-security-common/src/main/java/org/springframework/cloud/stream/app/security/common/AppStarterWebFluxSecurityAutoConfiguration.java b/applications/stream-applications-core/stream-applications-security-common/src/main/java/org/springframework/cloud/stream/app/security/common/AppStarterWebFluxSecurityAutoConfiguration.java index 31474a71..db77166e 100644 --- a/applications/stream-applications-core/stream-applications-security-common/src/main/java/org/springframework/cloud/stream/app/security/common/AppStarterWebFluxSecurityAutoConfiguration.java +++ b/applications/stream-applications-core/stream-applications-security-common/src/main/java/org/springframework/cloud/stream/app/security/common/AppStarterWebFluxSecurityAutoConfiguration.java @@ -36,21 +36,22 @@ import org.springframework.web.reactive.config.WebFluxConfigurer; /** * @author Artem Bilan + * @author David Turanski * @since 3.0 */ @Conditional(OnHttpCsrfOrSecurityDisabled.class) @Configuration -@ConditionalOnClass({Flux.class, EnableWebFluxSecurity.class, WebFilterChainProxy.class, WebFluxConfigurer.class}) +@ConditionalOnClass({ Flux.class, EnableWebFluxSecurity.class, WebFilterChainProxy.class, WebFluxConfigurer.class }) @ConditionalOnMissingBean(WebFilterChainProxy.class) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) -@AutoConfigureBefore({ReactiveManagementWebSecurityAutoConfiguration.class, - ReactiveSecurityAutoConfiguration.class}) +@AutoConfigureBefore({ ReactiveManagementWebSecurityAutoConfiguration.class, + ReactiveSecurityAutoConfiguration.class }) @EnableConfigurationProperties(AppStarterWebSecurityAutoConfigurationProperties.class) public class AppStarterWebFluxSecurityAutoConfiguration { @Bean public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http, - AppStarterWebSecurityAutoConfigurationProperties securityProperties) { + AppStarterWebSecurityAutoConfigurationProperties securityProperties) { if (!securityProperties.isCsrfEnabled()) { http.csrf().disable(); } @@ -59,6 +60,13 @@ public class AppStarterWebFluxSecurityAutoConfiguration { .anyExchange() .permitAll(); } + else { + http.authorizeExchange().pathMatchers("/actuator/health", "/actuator/info", "/actuator/bindings") + .permitAll().anyExchange().authenticated(); + http.httpBasic(); + http.formLogin(); + + } return http.build(); } diff --git a/applications/stream-applications-core/stream-applications-security-common/src/main/java/org/springframework/cloud/stream/app/security/common/AppStarterWebSecurityAutoConfiguration.java b/applications/stream-applications-core/stream-applications-security-common/src/main/java/org/springframework/cloud/stream/app/security/common/AppStarterWebSecurityAutoConfiguration.java index 300d53af..45173676 100644 --- a/applications/stream-applications-core/stream-applications-security-common/src/main/java/org/springframework/cloud/stream/app/security/common/AppStarterWebSecurityAutoConfiguration.java +++ b/applications/stream-applications-core/stream-applications-security-common/src/main/java/org/springframework/cloud/stream/app/security/common/AppStarterWebSecurityAutoConfiguration.java @@ -16,6 +16,7 @@ package org.springframework.cloud.stream.app.security.common; +import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -27,13 +28,13 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; /** * @author Christian Tzolov * @author Artem Bilan + * @author David Turanski * @since 2.1 */ @Conditional(OnHttpCsrfOrSecurityDisabled.class) @@ -41,7 +42,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur @ConditionalOnClass(WebSecurityConfigurerAdapter.class) @ConditionalOnMissingBean(WebSecurityConfigurerAdapter.class) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) -@AutoConfigureBefore({ManagementWebSecurityAutoConfiguration.class, SecurityAutoConfiguration.class}) +@AutoConfigureBefore({ ManagementWebSecurityAutoConfiguration.class, SecurityAutoConfiguration.class }) @EnableConfigurationProperties(AppStarterWebSecurityAutoConfigurationProperties.class) @EnableWebSecurity public class AppStarterWebSecurityAutoConfiguration { @@ -50,24 +51,23 @@ public class AppStarterWebSecurityAutoConfiguration { WebSecurityConfigurerAdapter appStarterWebSecurityConfigurerAdapter( AppStarterWebSecurityAutoConfigurationProperties securityProperties) { - return new WebSecurityConfigurerAdapter() { @Override protected void configure(HttpSecurity http) throws Exception { - super.configure(http); if (!securityProperties.isCsrfEnabled()) { http.csrf().disable(); } - } - - @Override - public void configure(WebSecurity builder) { - if (!securityProperties.isEnabled()) { - builder.ignoring().antMatchers("/**"); + if (securityProperties.isEnabled()) { + http.authorizeRequests() + .requestMatchers(EndpointRequest.to("health", "info", "bindings")).permitAll() + .requestMatchers(EndpointRequest.toAnyEndpoint()).authenticated() + .and().formLogin().and().httpBasic(); + } + else { + http.authorizeRequests().anyRequest().permitAll(); } } - }; } diff --git a/applications/stream-applications-core/stream-applications-security-common/src/main/java/org/springframework/cloud/stream/app/security/common/OnHttpCsrfOrSecurityDisabled.java b/applications/stream-applications-core/stream-applications-security-common/src/main/java/org/springframework/cloud/stream/app/security/common/OnHttpCsrfOrSecurityDisabled.java index bcca41a1..beed08c6 100644 --- a/applications/stream-applications-core/stream-applications-security-common/src/main/java/org/springframework/cloud/stream/app/security/common/OnHttpCsrfOrSecurityDisabled.java +++ b/applications/stream-applications-core/stream-applications-security-common/src/main/java/org/springframework/cloud/stream/app/security/common/OnHttpCsrfOrSecurityDisabled.java @@ -32,11 +32,11 @@ class OnHttpCsrfOrSecurityDisabled extends AnyNestedCondition { super(ConfigurationPhase.PARSE_CONFIGURATION); } - @ConditionalOnProperty(name = "spring.cloud.streamapp.security.enabled", havingValue = "false") + @ConditionalOnProperty(name = "spring.cloud.streamapp.security.enabled", havingValue = "false", matchIfMissing = true) static class SecurityDisabled { } - @ConditionalOnProperty(name = "spring.cloud.streamapp.security.csrf-enabled", havingValue = "false") + @ConditionalOnProperty(name = "spring.cloud.streamapp.security.csrf-enabled", havingValue = "false", matchIfMissing = true) static class HttpCsrfDisabled { } diff --git a/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityDisabledManagementSecurityEnabledTests.java b/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityDisabledManagementSecurityEnabledTests.java index be25cbff..ef426af6 100644 --- a/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityDisabledManagementSecurityEnabledTests.java +++ b/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityDisabledManagementSecurityEnabledTests.java @@ -16,8 +16,10 @@ package org.springframework.cloud.stream.app.security.common; +import java.util.List; import java.util.Map; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; @@ -28,12 +30,13 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat; /** * @author Artem Bilan + * @author David Turanski * @since 3.0 */ @TestPropertySource(properties = { "spring.main.web-application-type=reactive", "spring.cloud.streamapp.security.enabled=false", - "management.endpoints.web.exposure.include=health,info,env", + "management.endpoints.web.exposure.include=health,info,bindings,env", "info.name=MY TEST APP"}) public class ReactiveSecurityDisabledManagementSecurityEnabledTests extends AbstractSecurityCommonTests { @@ -58,6 +61,13 @@ public class ReactiveSecurityDisabledManagementSecurityEnabledTests extends Abst assertThat(info.get("name")).isEqualTo("MY TEST APP"); } + @Test + @SuppressWarnings("rawtypes") + public void testBindingsEndpoint() { + ResponseEntity response = this.restTemplate.getForEntity("/actuator/bindings", List.class); + Assertions.assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + @Test @SuppressWarnings("rawtypes") public void testEnvEndpoint() { diff --git a/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityEnabledManagementSecurityDisabledAuthorizedAccessTests.java b/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityEnabledAuthorizedAccessTests.java similarity index 76% rename from applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityEnabledManagementSecurityDisabledAuthorizedAccessTests.java rename to applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityEnabledAuthorizedAccessTests.java index a2bdd572..63bdf1d6 100644 --- a/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityEnabledManagementSecurityDisabledAuthorizedAccessTests.java +++ b/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityEnabledAuthorizedAccessTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 the original author or authors. + * Copyright 2021-2021 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. @@ -16,6 +16,7 @@ package org.springframework.cloud.stream.app.security.common; +import java.util.List; import java.util.Map; import org.junit.jupiter.api.BeforeEach; @@ -32,21 +33,21 @@ import static org.assertj.core.api.Assertions.assertThat; /** * @author Christian Tzolov + * @author David Turanski * @since 3.0 */ @TestPropertySource(properties = { "spring.main.web-application-type=reactive", - "org.springframework.boot.actuate.autoconfigure.security.reactive.ReactiveManagementWebSecurityAutoConfiguration" - + ",org.springframework.cloud.stream.app.security.common.AppStarterWebFluxSecurityAutoConfiguration", - "management.endpoints.web.exposure.include=health,info,env", - "info.name=MY TEST APP"}) -public class ReactiveSecurityEnabledManagementSecurityDisabledAuthorizedAccessTests extends AbstractSecurityCommonTests { + "management.endpoints.web.exposure.include=*", + "info.name=MY TEST APP" }) +public class ReactiveSecurityEnabledAuthorizedAccessTests + extends AbstractSecurityCommonTests { @Autowired private SecurityProperties securityProperties; @BeforeEach - public void before() { + public void authenticate() { restTemplate.getRestTemplate().getInterceptors().add(new BasicAuthenticationInterceptor( securityProperties.getUser().getName(), securityProperties.getUser().getPassword())); } @@ -72,12 +73,25 @@ public class ReactiveSecurityEnabledManagementSecurityDisabledAuthorizedAccessTe assertThat(info.get("name")).isEqualTo("MY TEST APP"); } + @Test + @SuppressWarnings("rawtypes") + public void testBindingsEndpoint() { + ResponseEntity response = this.restTemplate.getForEntity("/actuator/bindings", List.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + @Test + @SuppressWarnings("rawtypes") + public void testBeansEndpoint() { + ResponseEntity response = this.restTemplate.getForEntity("/actuator/beans", Object.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + @Test @SuppressWarnings("rawtypes") public void testEnvEndpoint() { ResponseEntity response = this.restTemplate.getForEntity("/actuator/env", Map.class); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(response.hasBody()).isTrue(); } } diff --git a/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityEnabledManagementSecurityDisabledUnauthorizedAccessTests.java b/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityEnabledManagementSecurityDisabledUnauthorizedAccessTests.java index 92ddd90e..e89141bb 100644 --- a/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityEnabledManagementSecurityDisabledUnauthorizedAccessTests.java +++ b/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityEnabledManagementSecurityDisabledUnauthorizedAccessTests.java @@ -16,6 +16,7 @@ package org.springframework.cloud.stream.app.security.common; +import java.util.List; import java.util.Map; import org.junit.jupiter.api.Test; @@ -29,14 +30,15 @@ import static org.assertj.core.api.Assertions.assertThat; /** * @author Christian Tzolov * @author Artem Bilan + * @Author David Turanski * @since 3.0 */ @TestPropertySource(properties = { "spring.main.web-application-type=reactive", "spring.autoconfigure.exclude=" + - "org.springframework.boot.actuate.autoconfigure.security.reactive.ReactiveManagementWebSecurityAutoConfiguration" - + ",org.springframework.cloud.stream.app.security.common.AppStarterWebFluxSecurityAutoConfiguration", - "management.endpoints.web.exposure.include=health,info"}) + "org.springframework.boot.actuate.autoconfigure.security.reactive.ReactiveManagementWebSecurityAutoConfiguration," + + "org.springframework.cloud.stream.app.security.common.AppStarterWebFluxSecurityAutoConfiguration", + "management.endpoints.web.exposure.include=health,info,bindings"}) public class ReactiveSecurityEnabledManagementSecurityDisabledUnauthorizedAccessTests extends AbstractSecurityCommonTests { @Test @@ -53,6 +55,13 @@ public class ReactiveSecurityEnabledManagementSecurityDisabledUnauthorizedAccess assertThat(response.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED); } + @Test + @SuppressWarnings("rawtypes") + public void testBindingsEndpoint() { + ResponseEntity response = this.restTemplate.getForEntity("/actuator/bindings", List.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED); + } + @Test @SuppressWarnings("rawtypes") public void testEnvEndpoint() { diff --git a/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityEnabledManagementSecurityEnabledTests.java b/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityEnabledManagementSecurityEnabledTests.java index 1b0e37fd..2a7089b8 100644 --- a/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityEnabledManagementSecurityEnabledTests.java +++ b/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityEnabledManagementSecurityEnabledTests.java @@ -16,6 +16,7 @@ package org.springframework.cloud.stream.app.security.common; +import java.util.List; import java.util.Map; import org.junit.jupiter.api.Test; @@ -29,11 +30,12 @@ import static org.assertj.core.api.Assertions.assertThat; /** * @author Christian Tzolov * @author Artem Bilan + * @author David Turanski * @since 3.0 */ @TestPropertySource(properties = { "spring.main.web-application-type=reactive", - "management.endpoints.web.exposure.include=health,info,env", + "management.endpoints.web.exposure.include=health,info,env,bindings", "info.name=MY TEST APP"}) public class ReactiveSecurityEnabledManagementSecurityEnabledTests extends AbstractSecurityCommonTests { @@ -52,10 +54,17 @@ public class ReactiveSecurityEnabledManagementSecurityEnabledTests extends Abstr @SuppressWarnings("rawtypes") public void testInfoEndpoint() { ResponseEntity response = this.restTemplate.getForEntity("/actuator/info", Map.class); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); } - // The ManagementWebSecurityAutoConfiguration exposes only Info and Health endpoint not Env! + @Test + @SuppressWarnings("rawtypes") + public void testBindingsEndpoint() { + ResponseEntity response = this.restTemplate.getForEntity("/actuator/bindings", List.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + // The ManagementWebSecurityAutoConfiguration exposes only info,health, bindings endpoint not env! @Test @SuppressWarnings("rawtypes") public void testEnvEndpoint() { diff --git a/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityDisabledManagementSecurityEnabledTests.java b/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityDisabledManagementSecurityEnabledTests.java index 30867233..d901cf91 100644 --- a/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityDisabledManagementSecurityEnabledTests.java +++ b/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityDisabledManagementSecurityEnabledTests.java @@ -16,6 +16,7 @@ package org.springframework.cloud.stream.app.security.common; +import java.util.List; import java.util.Map; import org.junit.jupiter.api.Test; @@ -29,12 +30,13 @@ import static org.assertj.core.api.Assertions.assertThat; /** * @author Christian Tzolov * @author Artem Bilan + * @author David Turanski * @since 3.0 */ @TestPropertySource(properties = { "spring.main.web-application-type=servlet", "spring.cloud.streamapp.security.enabled=false", - "management.endpoints.web.exposure.include=health,info,env", + "management.endpoints.web.exposure.include=health,info,bindings,env", "info.name=MY TEST APP"}) public class SecurityDisabledManagementSecurityEnabledTests extends AbstractSecurityCommonTests { @@ -58,6 +60,13 @@ public class SecurityDisabledManagementSecurityEnabledTests extends AbstractSecu assertThat(info.get("name")).isEqualTo("MY TEST APP"); } + @Test + @SuppressWarnings("rawtypes") + public void testBindingsEndpoint() { + ResponseEntity response = this.restTemplate.getForEntity("/actuator/bindings", List.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + @Test @SuppressWarnings("rawtypes") public void testEnvEndpoint() { diff --git a/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityEnabledManagementSecurityDisabledAuthorizedAccessTests.java b/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityEnabledAuthorizedAccessTests.java similarity index 84% rename from applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityEnabledManagementSecurityDisabledAuthorizedAccessTests.java rename to applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityEnabledAuthorizedAccessTests.java index be0b7147..3ac04789 100644 --- a/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityEnabledManagementSecurityDisabledAuthorizedAccessTests.java +++ b/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityEnabledAuthorizedAccessTests.java @@ -16,6 +16,7 @@ package org.springframework.cloud.stream.app.security.common; +import java.util.List; import java.util.Map; import org.junit.jupiter.api.BeforeEach; @@ -33,22 +34,20 @@ import static org.assertj.core.api.Assertions.assertThat; /** * @author Christian Tzolov * @author Artem Bilan + * @author David Turanski * @since 3.0 */ @TestPropertySource(properties = { "spring.main.web-application-type=servlet", - "spring.autoconfigure.exclude=org.springframework.boot.actuate.autoconfigure.security.servlet" + - ".ManagementWebSecurityAutoConfiguration" - + ",org.springframework.cloud.stream.app.security.common.AppStarterWebSecurityAutoConfiguration", - "management.endpoints.web.exposure.include=health,info,env", + "management.endpoints.web.exposure.include=health,info,bindings,env", "info.name=MY TEST APP"}) -public class SecurityEnabledManagementSecurityDisabledAuthorizedAccessTests extends AbstractSecurityCommonTests { +public class SecurityEnabledAuthorizedAccessTests extends AbstractSecurityCommonTests { @Autowired private SecurityProperties securityProperties; @BeforeEach - public void before() { + public void authenticate() { restTemplate.getRestTemplate().getInterceptors().add(new BasicAuthenticationInterceptor( securityProperties.getUser().getName(), securityProperties.getUser().getPassword())); } @@ -73,6 +72,13 @@ public class SecurityEnabledManagementSecurityDisabledAuthorizedAccessTests exte assertThat(info.get("name")).isEqualTo("MY TEST APP"); } + @Test + @SuppressWarnings("rawtypes") + public void testBindingsEndpoint() { + ResponseEntity response = this.restTemplate.getForEntity("/actuator/bindings", List.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + @Test @SuppressWarnings("rawtypes") public void testEnvEndpoint() { diff --git a/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityEnabledManagementSecurityDisabledUnauthorizedAccessTests.java b/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityEnabledManagementSecurityDisabledUnauthorizedAccessTests.java index 5e72ff62..73e73f1d 100644 --- a/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityEnabledManagementSecurityDisabledUnauthorizedAccessTests.java +++ b/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityEnabledManagementSecurityDisabledUnauthorizedAccessTests.java @@ -29,6 +29,7 @@ import static org.assertj.core.api.Assertions.assertThat; /** * @author Christian Tzolov * @author Artem Bilan + * @Author David Turanski * @since 3.0 */ @TestPropertySource(properties = { @@ -36,7 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat; "spring.autoconfigure.exclude=" + "org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration" + ",org.springframework.cloud.stream.app.security.common.AppStarterWebSecurityAutoConfiguration", - "management.endpoints.web.exposure.include=health,info"}) + "management.endpoints.web.exposure.include=health,info,bindings,env" }) public class SecurityEnabledManagementSecurityDisabledUnauthorizedAccessTests extends AbstractSecurityCommonTests { @Test @@ -59,6 +60,13 @@ public class SecurityEnabledManagementSecurityDisabledUnauthorizedAccessTests ex assertThat(info.get("error")).isEqualTo("Unauthorized"); } + @Test + @SuppressWarnings("rawtypes") + public void testBindingsEndpoint() { + ResponseEntity response = this.restTemplate.getForEntity("/actuator/bindings", Object.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED); + } + @Test @SuppressWarnings("rawtypes") public void testEnvEndpoint() { diff --git a/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityEnabledManagementSecurityEnabledTests.java b/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityEnabledManagementSecurityEnabledTests.java index c41eef9a..905aea68 100644 --- a/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityEnabledManagementSecurityEnabledTests.java +++ b/applications/stream-applications-core/stream-applications-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityEnabledManagementSecurityEnabledTests.java @@ -51,7 +51,7 @@ public class SecurityEnabledManagementSecurityEnabledTests extends AbstractSecur @SuppressWarnings("rawtypes") public void testInfoEndpoint() { ResponseEntity response = this.restTemplate.getForEntity("/actuator/info", Map.class); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); } // The ManagementWebSecurityAutoConfiguration exposes only Info and Health endpoint not Env! diff --git a/applications/stream-applications-integration-tests/src/test/java/org/springframework/cloud/stream/app/integration/test/source/time/KafkaTimeSourceTests.java b/applications/stream-applications-integration-tests/src/test/java/org/springframework/cloud/stream/app/integration/test/source/time/KafkaTimeSourceTests.java index 8a37e58f..e0c2257d 100644 --- a/applications/stream-applications-integration-tests/src/test/java/org/springframework/cloud/stream/app/integration/test/source/time/KafkaTimeSourceTests.java +++ b/applications/stream-applications-integration-tests/src/test/java/org/springframework/cloud/stream/app/integration/test/source/time/KafkaTimeSourceTests.java @@ -37,7 +37,6 @@ class KafkaTimeSourceTests extends TimeSourceTests { static StreamAppContainer source = new KafkaStreamAppContainer(StreamAppContainerTestUtils .imageName(StreamAppContainerTestUtils.SPRINGCLOUDSTREAM_REPOSITOTRY, "time-source-kafka", VERSION)) .withCommand("--server.port", "8080") - .withEnv("SPRING_CLOUD_STREAMAPP_SECURITY_ENABLED", "false") .withExposedPorts(8080); @Test diff --git a/stream-applications-build/pom.xml b/stream-applications-build/pom.xml index 60f2f06d..eea15c0b 100644 --- a/stream-applications-build/pom.xml +++ b/stream-applications-build/pom.xml @@ -339,7 +339,6 @@ org.apache.maven.plugins maven-surefire-plugin - !integration integration