From 3cc658b47cbed51600b4856d322974bde3d872c0 Mon Sep 17 00:00:00 2001 From: Alexis de Talhouët Date: Mon, 4 Mar 2019 21:37:27 -0500 Subject: Add gRPC & REST basic auth support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Iaa187a8288a9c84aa80b596a14e66de10a9b7501 Issue-ID: CCSDK-1055 Signed-off-by: Alexis de Talhouët --- ms/blueprintsprocessor/application/pom.xml | 8 +- .../blueprintsprocessor/BlueprintGRPCServer.java | 13 +-- .../blueprintsprocessor/BlueprintHttpServer.java | 8 +- .../BlueprintProcessorApplication.java | 5 +- .../ccsdk/apps/blueprintsprocessor/WebConfig.java | 47 +++++++++-- .../security/AuthenticationManager.java | 40 +++++++++ .../security/BasicAuthServerInterceptor.java | 97 ++++++++++++++++++++++ .../security/SecurityConfiguration.java | 59 +++++++++++++ .../security/SecurityContextRepository.java | 75 +++++++++++++++++ .../src/main/resources/application.properties | 3 + .../src/test/resources/application.properties | 6 ++ .../modules/inbounds/selfservice-api/pom.xml | 6 ++ .../api/BluePrintManagementGRPCHandler.kt | 5 +- .../api/BluePrintProcessingGRPCHandler.kt | 4 +- .../selfservice/api/ExecutionServiceController.kt | 5 +- .../selfservice/api/ExecutionServiceHandlerTest.kt | 3 +- 16 files changed, 358 insertions(+), 26 deletions(-) create mode 100644 ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/apps/blueprintsprocessor/security/AuthenticationManager.java create mode 100644 ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/apps/blueprintsprocessor/security/BasicAuthServerInterceptor.java create mode 100644 ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/apps/blueprintsprocessor/security/SecurityConfiguration.java create mode 100644 ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/apps/blueprintsprocessor/security/SecurityContextRepository.java diff --git a/ms/blueprintsprocessor/application/pom.xml b/ms/blueprintsprocessor/application/pom.xml index 83dc7061..f42cdfad 100755 --- a/ms/blueprintsprocessor/application/pom.xml +++ b/ms/blueprintsprocessor/application/pom.xml @@ -17,7 +17,8 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - + 4.0.0 org.onap.ccsdk.apps.blueprintsprocessor @@ -40,6 +41,11 @@ spring-boot-devtools runtime + + org.springframework.boot + spring-boot-starter-security + + org.onap.ccsdk.apps.blueprintsprocessor diff --git a/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/apps/blueprintsprocessor/BlueprintGRPCServer.java b/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/apps/blueprintsprocessor/BlueprintGRPCServer.java index 86fdccd4..3ac1a6e6 100644 --- a/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/apps/blueprintsprocessor/BlueprintGRPCServer.java +++ b/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/apps/blueprintsprocessor/BlueprintGRPCServer.java @@ -18,6 +18,7 @@ package org.onap.ccsdk.apps.blueprintsprocessor; import io.grpc.Server; import io.grpc.ServerBuilder; +import org.onap.ccsdk.apps.blueprintsprocessor.security.BasicAuthServerInterceptor; import org.onap.ccsdk.apps.blueprintsprocessor.selfservice.api.BluePrintManagementGRPCHandler; import org.onap.ccsdk.apps.blueprintsprocessor.selfservice.api.BluePrintProcessingGRPCHandler; import org.slf4j.Logger; @@ -37,9 +38,10 @@ public class BlueprintGRPCServer implements ApplicationListener authenticate(Authentication authentication) { + try { + return Mono.just(authenticationProvider.authenticate(authentication)); + } catch (AuthenticationException e) { + return Mono.error(e); + } + } +} \ No newline at end of file diff --git a/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/apps/blueprintsprocessor/security/BasicAuthServerInterceptor.java b/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/apps/blueprintsprocessor/security/BasicAuthServerInterceptor.java new file mode 100644 index 00000000..db0bfce4 --- /dev/null +++ b/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/apps/blueprintsprocessor/security/BasicAuthServerInterceptor.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2019 Bell Canada. + * + * 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 + * + * http://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.onap.ccsdk.apps.blueprintsprocessor.security; + +import com.google.common.base.Strings; +import io.grpc.Metadata; +import io.grpc.ServerCall; +import io.grpc.ServerCallHandler; +import io.grpc.ServerInterceptor; +import io.grpc.Status; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; + +@Component +public class BasicAuthServerInterceptor implements ServerInterceptor { + + private static Logger log = LoggerFactory.getLogger(BasicAuthServerInterceptor.class); + + @Autowired + private AuthenticationManager authenticationManager; + + + @Override + public ServerCall.Listener interceptCall( + ServerCall call, + Metadata headers, + ServerCallHandler next) { + String authHeader = headers.get(Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER)); + + if (Strings.isNullOrEmpty(authHeader)) { + throw Status.UNAUTHENTICATED.withDescription("Missing required authentication").asRuntimeException(); + + } + + try { + String[] tokens = decodeBasicAuth(authHeader); + String username = tokens[0]; + + log.info("Basic Authentication Authorization header found for user: {}", username); + + Authentication authRequest = new UsernamePasswordAuthenticationToken(username, tokens[1]); + Authentication authResult = authenticationManager.authenticate(authRequest).block(); + + log.info("Authentication success: {}", authResult); + + SecurityContextHolder.getContext().setAuthentication(authResult); + + } catch (AuthenticationException e) { + SecurityContextHolder.clearContext(); + + log.info("Authentication request failed: {}", e.getMessage()); + + throw Status.UNAUTHENTICATED.withDescription(e.getMessage()).withCause(e).asRuntimeException(); + } + + return next.startCall(call, headers); + } + + private String[] decodeBasicAuth(String authHeader) { + String basicAuth; + try { + basicAuth = new String(Base64.getDecoder().decode(authHeader.substring(6).getBytes(StandardCharsets.UTF_8)), + StandardCharsets.UTF_8); + } catch (IllegalArgumentException | IndexOutOfBoundsException e) { + throw new BadCredentialsException("Failed to decode basic authentication token"); + } + + int delim = basicAuth.indexOf(':'); + if (delim == -1) { + throw new BadCredentialsException("Failed to decode basic authentication token"); + } + + return new String[]{basicAuth.substring(0, delim), basicAuth.substring(delim + 1)}; + } +} \ No newline at end of file diff --git a/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/apps/blueprintsprocessor/security/SecurityConfiguration.java b/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/apps/blueprintsprocessor/security/SecurityConfiguration.java new file mode 100644 index 00000000..7ddc42cc --- /dev/null +++ b/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/apps/blueprintsprocessor/security/SecurityConfiguration.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2019 Bell Canada. + * + * 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 + * + * http://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.onap.ccsdk.apps.blueprintsprocessor.security; + +import java.util.Collections; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; + +@Configuration +public class SecurityConfiguration { + + @Value("${security.user.name}") + private String username; + + @Value("${security.user.password}") + private String password; + + @Bean + public UserDetailsService inMemoryUserService() { + UserDetails user = new User(username, password, + Collections.singletonList(new SimpleGrantedAuthority("USER"))); + return new InMemoryUserDetailsManager(user); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Bean + public AuthenticationProvider inMemoryAuthenticationProvider() { + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + provider.setUserDetailsService(inMemoryUserService()); + return provider; + } +} \ No newline at end of file diff --git a/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/apps/blueprintsprocessor/security/SecurityContextRepository.java b/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/apps/blueprintsprocessor/security/SecurityContextRepository.java new file mode 100644 index 00000000..f9e184a1 --- /dev/null +++ b/ms/blueprintsprocessor/application/src/main/java/org/onap/ccsdk/apps/blueprintsprocessor/security/SecurityContextRepository.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2019 Bell Canada. + * + * 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 + * + * http://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.onap.ccsdk.apps.blueprintsprocessor.security; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextImpl; +import org.springframework.security.web.server.context.ServerSecurityContextRepository; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +@Component +public class SecurityContextRepository implements ServerSecurityContextRepository { + + @Autowired + private AuthenticationManager authenticationManager; + + @Override + public Mono save(ServerWebExchange swe, SecurityContext sc) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Mono load(ServerWebExchange swe) { + ServerHttpRequest request = swe.getRequest(); + String authHeader = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION); + if (authHeader != null && authHeader.startsWith("Basic")) { + String[] tokens = decodeBasicAuth(authHeader); + String username = tokens[0]; + String password = tokens[1]; + Authentication auth = new UsernamePasswordAuthenticationToken(username, password); + return this.authenticationManager.authenticate(auth).map(SecurityContextImpl::new); + } else { + return Mono.empty(); + } + } + + private String[] decodeBasicAuth(String authHeader) { + String basicAuth; + try { + basicAuth = new String(Base64.getDecoder().decode(authHeader.substring(6).getBytes(StandardCharsets.UTF_8)), + StandardCharsets.UTF_8); + } catch (IllegalArgumentException | IndexOutOfBoundsException e) { + throw new BadCredentialsException("Failed to decode basic authentication token"); + } + + int delim = basicAuth.indexOf(':'); + if (delim == -1) { + throw new BadCredentialsException("Failed to decode basic authentication token"); + } + + return new String[]{basicAuth.substring(0, delim), basicAuth.substring(delim + 1)}; + } +} \ No newline at end of file diff --git a/ms/blueprintsprocessor/application/src/main/resources/application.properties b/ms/blueprintsprocessor/application/src/main/resources/application.properties index cfef4f82..e955c97c 100755 --- a/ms/blueprintsprocessor/application/src/main/resources/application.properties +++ b/ms/blueprintsprocessor/application/src/main/resources/application.properties @@ -36,3 +36,6 @@ blueprintsprocessor.db.primary.hibernateDialect=org.hibernate.dialect.MySQL5Inno # Python executor blueprints.processor.functions.python.executor.executionPath=/opt/app/onap/scripts/jython/ccsdk_blueprints blueprints.processor.functions.python.executor.modulePaths=/opt/app/onap/scripts/jython/ccsdk_blueprints,/opt/app/onap/scripts/jython/ccsdk_netconf + +security.user.password: {bcrypt}$2a$10$duaUzVUVW0YPQCSIbGEkQOXwafZGwQ/b32/Ys4R1iwSSawFgz7QNu +security.user.name: ccsdkapps diff --git a/ms/blueprintsprocessor/application/src/test/resources/application.properties b/ms/blueprintsprocessor/application/src/test/resources/application.properties index 2b5bea10..39302451 100644 --- a/ms/blueprintsprocessor/application/src/test/resources/application.properties +++ b/ms/blueprintsprocessor/application/src/test/resources/application.properties @@ -17,6 +17,9 @@ # # Web server config server.port=8080 +blueprintsprocessor.grpcEnable=false +blueprintsprocessor.httpPort=8080 +blueprintsprocessor.grpcPort=9111 # Blueprint Processor File Execution and Handling Properties blueprintsprocessor.blueprintDeployPath=/opt/app/onap/blueprints/deploy blueprintsprocessor.blueprintArchivePath=/opt/app/onap/blueprints/archive @@ -32,3 +35,6 @@ blueprintsprocessor.db.primary.hibernateDialect=org.hibernate.dialect.H2Dialect # Python executor blueprints.processor.functions.python.executor.executionPath=/opt/app/onap/scripts/jython blueprints.processor.functions.python.executor.modulePaths=/opt/app/onap/scripts/jython + +security.user.password: {bcrypt}$2a$10$duaUzVUVW0YPQCSIbGEkQOXwafZGwQ/b32/Ys4R1iwSSawFgz7QNu +security.user.name: ccsdkapps diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/pom.xml b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/pom.xml index c05b84ad..f538a152 100755 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/pom.xml +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/pom.xml @@ -32,6 +32,12 @@ Blueprints Processor Selfservice API + + + org.springframework.security + spring-security-core + + org.onap.ccsdk.apps.components proto-definition diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/selfservice/api/BluePrintManagementGRPCHandler.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/selfservice/api/BluePrintManagementGRPCHandler.kt index fb0bc567..d689187e 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/selfservice/api/BluePrintManagementGRPCHandler.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/selfservice/api/BluePrintManagementGRPCHandler.kt @@ -28,16 +28,18 @@ import org.onap.ccsdk.apps.controllerblueprints.management.api.BluePrintManageme import org.onap.ccsdk.apps.controllerblueprints.management.api.BluePrintManagementOutput import org.onap.ccsdk.apps.controllerblueprints.management.api.BluePrintManagementServiceGrpc import org.slf4j.LoggerFactory +import org.springframework.security.access.prepost.PreAuthorize import org.springframework.stereotype.Service import java.io.File @Service -class BluePrintManagementGRPCHandler(private val bluePrintCoreConfiguration: BluePrintCoreConfiguration, +open class BluePrintManagementGRPCHandler(private val bluePrintCoreConfiguration: BluePrintCoreConfiguration, private val bluePrintCatalogService: BluePrintCatalogService) : BluePrintManagementServiceGrpc.BluePrintManagementServiceImplBase() { private val log = LoggerFactory.getLogger(BluePrintManagementGRPCHandler::class.java) + @PreAuthorize("hasRole('USER')") override fun uploadBlueprint(request: BluePrintManagementInput, responseObserver: StreamObserver) { val blueprintName = request.blueprintName val blueprintVersion = request.blueprintVersion @@ -61,6 +63,7 @@ class BluePrintManagementGRPCHandler(private val bluePrintCoreConfiguration: Blu } } + @PreAuthorize("hasRole('USER')") override fun removeBlueprint(request: BluePrintManagementInput, responseObserver: StreamObserver) { val blueprintName = request.blueprintName val blueprintVersion = request.blueprintVersion diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/selfservice/api/BluePrintProcessingGRPCHandler.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/selfservice/api/BluePrintProcessingGRPCHandler.kt index edb1d31d..aadbec83 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/selfservice/api/BluePrintProcessingGRPCHandler.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/selfservice/api/BluePrintProcessingGRPCHandler.kt @@ -23,14 +23,16 @@ import org.onap.ccsdk.apps.controllerblueprints.processing.api.BluePrintProcessi import org.onap.ccsdk.apps.controllerblueprints.processing.api.ExecutionServiceInput import org.onap.ccsdk.apps.controllerblueprints.processing.api.ExecutionServiceOutput import org.slf4j.LoggerFactory +import org.springframework.security.access.prepost.PreAuthorize import org.springframework.stereotype.Service @Service -class BluePrintProcessingGRPCHandler(private val bluePrintCoreConfiguration: BluePrintCoreConfiguration, +open class BluePrintProcessingGRPCHandler(private val bluePrintCoreConfiguration: BluePrintCoreConfiguration, private val executionServiceHandler: ExecutionServiceHandler) : BluePrintProcessingServiceGrpc.BluePrintProcessingServiceImplBase() { private val log = LoggerFactory.getLogger(BluePrintProcessingGRPCHandler::class.java) + @PreAuthorize("hasRole('USER')") override fun process( responseObserver: StreamObserver): StreamObserver { diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt index 6477c067..16f0fa86 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/selfservice/api/ExecutionServiceController.kt @@ -23,6 +23,7 @@ import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ExecutionServiceOut import org.springframework.beans.factory.annotation.Autowired import org.springframework.http.MediaType import org.springframework.http.codec.multipart.FilePart +import org.springframework.security.access.prepost.PreAuthorize import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RequestMapping @@ -34,7 +35,7 @@ import reactor.core.publisher.Mono @RestController @RequestMapping("/api/v1/execution-service") -class ExecutionServiceController { +open class ExecutionServiceController { @Autowired lateinit var executionServiceHandler: ExecutionServiceHandler @@ -48,6 +49,7 @@ class ExecutionServiceController { @PostMapping(path = ["/upload"], consumes = [MediaType.MULTIPART_FORM_DATA_VALUE]) @ApiOperation(value = "Upload CBA", notes = "Takes a File and load it in the runtime database") @ResponseBody + @PreAuthorize("hasRole('USER')") fun upload(@RequestPart("file") parts: Mono): Mono { return parts .filter { it is FilePart } @@ -59,6 +61,7 @@ class ExecutionServiceController { @ApiOperation(value = "Resolve Resource Mappings", notes = "Takes the blueprint information and process as per the payload") @ResponseBody + @PreAuthorize("hasRole('USER')") fun process(@RequestBody executionServiceInput: ExecutionServiceInput): ExecutionServiceOutput { if (executionServiceInput.actionIdentifiers.mode == ACTION_MODE_ASYNC) { throw IllegalStateException("Can't process async request through the REST endpoint. Use gRPC for async processing.") diff --git a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/selfservice/api/ExecutionServiceHandlerTest.kt b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/selfservice/api/ExecutionServiceHandlerTest.kt index de120148..b730472e 100644 --- a/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/selfservice/api/ExecutionServiceHandlerTest.kt +++ b/ms/blueprintsprocessor/modules/inbounds/selfservice-api/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/selfservice/api/ExecutionServiceHandlerTest.kt @@ -24,6 +24,7 @@ import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ExecutionServiceInp import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintCatalogService import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.autoconfigure.security.SecurityProperties import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest import org.springframework.context.annotation.ComponentScan import org.springframework.core.io.ByteArrayResource @@ -39,7 +40,7 @@ import kotlin.test.assertTrue @RunWith(SpringRunner::class) @WebFluxTest -@ContextConfiguration(classes = [ExecutionServiceHandler::class, BluePrintCoreConfiguration::class, BluePrintCatalogService::class]) +@ContextConfiguration(classes = [ExecutionServiceHandler::class, BluePrintCoreConfiguration::class, BluePrintCatalogService::class, SecurityProperties::class]) @ComponentScan(basePackages = ["org.onap.ccsdk.apps.blueprintsprocessor", "org.onap.ccsdk.apps.controllerblueprints"]) @TestPropertySource(locations = ["classpath:application-test.properties"]) class ExecutionServiceHandlerTest { -- cgit 1.2.3-korg