Controller Blueprints Microservice
Add basic authentication for Controllerblueprint MS.
Change-Id: I145e26d6feba873e8d3ed82e4169cbaa425a277e
Issue-ID: CCSDK-590
Signed-off-by: Muthuramalingam, Brinda Santh(bs2796) <bs2796@att.com>
diff --git a/ms/controllerblueprints/application/etc/logback.xml b/ms/controllerblueprints/application/etc/logback.xml
index 0a75e60..6639705 100644
--- a/ms/controllerblueprints/application/etc/logback.xml
+++ b/ms/controllerblueprints/application/etc/logback.xml
@@ -33,6 +33,7 @@
<logger name="org.springframework" level="info"/>
<logger name="org.springframework.web" level="info"/>
+ <logger name="org.springframework.security.web.authentication" level="warn"/>
<logger name="org.hibernate" level="error"/>
<logger name="org.onap.ccsdk.apps" level="info"/>
diff --git a/ms/controllerblueprints/application/opt/app/onap/config/application.properties b/ms/controllerblueprints/application/opt/app/onap/config/application.properties
index d281482..e4457d0 100644
--- a/ms/controllerblueprints/application/opt/app/onap/config/application.properties
+++ b/ms/controllerblueprints/application/opt/app/onap/config/application.properties
@@ -18,6 +18,10 @@
ms_name=org.onap.ccsdk.apps.controllerblueprints
appVersion=1.0.0
+# Basic Authentication
+basic-auth.user-name=ccsdkapps
+basic-auth.hashed-pwd=$2a$10$MJxhNiOAffxbyrV9.rrOUewP9Q/ASg5Nit2cmP.yBaXGsVXo8BW3y
+
#logging.pattern.console=%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr($ threadId: {PID:- }){magenta} %clr(---){faint} %clr([ hostname: %X{hostname} serviceName: %X{serviceName} version: %X{version} transactionId: %X{transactionId} requestTimeStamp: %X{requestTimestamp} responseTimeStamp: %X{responseTimestamp} duration: %X{duration}]){yellow} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wex
logging.level.org.springframework.web=INFO
diff --git a/ms/controllerblueprints/application/pom.xml b/ms/controllerblueprints/application/pom.xml
index 24f4deb..9834924 100644
--- a/ms/controllerblueprints/application/pom.xml
+++ b/ms/controllerblueprints/application/pom.xml
@@ -55,6 +55,10 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-security</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
@@ -68,6 +72,11 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<scope>test</scope>
diff --git a/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/ApplicationExceptionHandler.java b/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/ApplicationExceptionHandler.java
index 6e9dcd7..78706d5 100644
--- a/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/ApplicationExceptionHandler.java
+++ b/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/ApplicationExceptionHandler.java
@@ -23,13 +23,19 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.web.csrf.InvalidCsrfTokenException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;
+import javax.naming.AuthenticationException;
+import java.nio.file.AccessDeniedException;
+
@ControllerAdvice
@RestController
@SuppressWarnings("unused")
@@ -43,6 +49,14 @@
return new ResponseEntity<>(exceptionResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
+ @ExceptionHandler({InvalidCsrfTokenException.class, AuthenticationException.class, BadCredentialsException.class, AccessDeniedException.class})
+ @ResponseStatus(value = HttpStatus.UNAUTHORIZED)
+ public final ResponseEntity<ErrorMessage> handleAuthenticationRequest(Exception ex, WebRequest request) {
+ log.error("Authentication Exception", ex);
+ ErrorMessage exceptionResponse = new ErrorMessage(ex.getMessage(), HttpStatus.UNAUTHORIZED.value(), ex.getLocalizedMessage());
+ return new ResponseEntity<>(exceptionResponse, HttpStatus.UNAUTHORIZED);
+ }
+
@ExceptionHandler({HttpMessageNotReadableException.class, MethodArgumentNotValidException.class,
HttpRequestMethodNotSupportedException.class})
public final ResponseEntity<ErrorMessage> handleBadRequest(Exception ex, WebRequest request) {
diff --git a/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/filters/ApplicationLoggingFilter.java b/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/filters/ApplicationLoggingFilter.java
index fbef55f..4476117 100644
--- a/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/filters/ApplicationLoggingFilter.java
+++ b/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/filters/ApplicationLoggingFilter.java
@@ -25,6 +25,8 @@
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
@@ -40,6 +42,7 @@
*/
@Component
@WebFilter(asyncSupported = true, urlPatterns = {"/*"})
+@Order(Ordered.HIGHEST_PRECEDENCE)
@SuppressWarnings("unused")
public class ApplicationLoggingFilter implements Filter {
private static Logger log = LoggerFactory.getLogger(ApplicationLoggingFilter.class);
diff --git a/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/security/ApplicationBasicAuthenticationEntryPoint.java b/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/security/ApplicationBasicAuthenticationEntryPoint.java
new file mode 100644
index 0000000..e3df3a6
--- /dev/null
+++ b/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/security/ApplicationBasicAuthenticationEntryPoint.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ *
+ * 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.controllerblueprints.security;
+
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
+import org.springframework.stereotype.Component;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+@Component
+public class ApplicationBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {
+
+ @Override
+ public void commence(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException authException)
+ throws IOException {
+ response.addHeader("WWW-Authenticate", "Basic realm=\"" + getRealmName() + "\"");
+ response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ setRealmName("CCSDK-APPS");
+ super.afterPropertiesSet();
+ }
+
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/security/ApplicationSecurityConfigurerAdapter.java b/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/security/ApplicationSecurityConfigurerAdapter.java
new file mode 100644
index 0000000..3a39d78
--- /dev/null
+++ b/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/security/ApplicationSecurityConfigurerAdapter.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ *
+ * 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.controllerblueprints.security;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+@SuppressWarnings("unused")
+@Configuration
+@EnableWebSecurity
+public class ApplicationSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
+
+ @Value("${basic-auth.user-name}")
+ private String userName;
+
+ @Value("${basic-auth.hashed-pwd}")
+ private String userHashedPassword;
+
+ private static EELFLogger log = EELFManager.getInstance().getLogger(ApplicationSecurityConfigurerAdapter.class);
+
+ @Autowired
+ private ApplicationBasicAuthenticationEntryPoint authenticationEntryPoint;
+
+ @Autowired
+ public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
+ log.info("User Id {} and hashed pwd : {}", userName, userHashedPassword);
+ auth.inMemoryAuthentication()
+ .withUser(userName).password(userHashedPassword)
+ .authorities("ROLE_USER");
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http.authorizeRequests()
+ .antMatchers("/actuator/health").permitAll()
+ .antMatchers("/**").authenticated()
+ .and()
+ .httpBasic()
+ .authenticationEntryPoint(authenticationEntryPoint);
+
+ http.csrf().disable();
+ }
+
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ return new BCryptPasswordEncoder();
+ }
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/test/java/org/onap/ccsdk/apps/controllerblueprints/ControllerBluprintsApplicationTest.java b/ms/controllerblueprints/application/src/test/java/org/onap/ccsdk/apps/controllerblueprints/ControllerBluprintsApplicationTest.java
index 61b5c50..7a5f952 100644
--- a/ms/controllerblueprints/application/src/test/java/org/onap/ccsdk/apps/controllerblueprints/ControllerBluprintsApplicationTest.java
+++ b/ms/controllerblueprints/application/src/test/java/org/onap/ccsdk/apps/controllerblueprints/ControllerBluprintsApplicationTest.java
@@ -1,6 +1,6 @@
/*
* Copyright © 2017-2018 AT&T Intellectual Property.
- * Modifications Copyright © 2018 IBM.
+ *
* 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
@@ -16,8 +16,6 @@
package org.onap.ccsdk.apps.controllerblueprints;
-import static org.assertj.core.api.Assertions.assertThat;
-
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -27,56 +25,40 @@
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
+import org.springframework.http.*;
+import org.springframework.http.client.support.BasicAuthorizationInterceptor;
import org.springframework.test.context.junit4.SpringRunner;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class ControllerBluprintsApplicationTest {
- private static EELFLogger log = EELFManager.getInstance().getLogger(ControllerBluprintsApplicationTest.class);
-
@Autowired
private TestRestTemplate restTemplate;
- private HttpHeaders headers;
- private ResponseEntity<ConfigModel> entity;
@Before
public void setUp(){
- headers = new HttpHeaders();
- headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
- entity = this.restTemplate
- .exchange("/api/v1/config-model/1", HttpMethod.GET, new HttpEntity<>(headers),ConfigModel.class);
-
+ BasicAuthorizationInterceptor bai = new BasicAuthorizationInterceptor("ccsdkapps", "ccsdkapps");
+ this.restTemplate.getRestTemplate().getInterceptors().add(bai);
}
@Test
public void testConfigModel() {
-
HttpHeaders headers = new HttpHeaders();
headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
ResponseEntity<ConfigModel> entity = this.restTemplate
.exchange("/api/v1/config-model/1", HttpMethod.GET, new HttpEntity<>(headers),ConfigModel.class);
-
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
Assert.assertNotNull("failed to get response Config model",entity.getBody());
}
@Test
public void testConfigModelFailure() {
-
HttpHeaders headers = new HttpHeaders();
headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
ResponseEntity<ConfigModel> entity = this.restTemplate
.exchange("/api/v1/config-model-not-found/1", HttpMethod.GET, new HttpEntity<>(headers),ConfigModel.class);
-
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
Assert.assertNotNull("failed to get response Config model",entity.getBody());
}
diff --git a/ms/controllerblueprints/application/src/test/java/org/onap/ccsdk/apps/controllerblueprints/VersionSplitTest.java b/ms/controllerblueprints/application/src/test/java/org/onap/ccsdk/apps/controllerblueprints/VersionSplitTest.java
index 9445e1d..995644f 100644
--- a/ms/controllerblueprints/application/src/test/java/org/onap/ccsdk/apps/controllerblueprints/VersionSplitTest.java
+++ b/ms/controllerblueprints/application/src/test/java/org/onap/ccsdk/apps/controllerblueprints/VersionSplitTest.java
@@ -16,21 +16,34 @@
package org.onap.ccsdk.apps.controllerblueprints;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
import org.apache.commons.lang3.StringUtils;
import org.junit.Assert;
import org.junit.Test;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+
/**
* VersionSplitTest
*
* @author Brinda Santh
*/
public class VersionSplitTest {
+ private static EELFLogger log = EELFManager.getInstance().getLogger(VersionSplitTest.class);
@Test
public void testVersionSplit() {
String version = "1.03.04";
String[] tokens = StringUtils.split(version, '.');
Assert.assertNotNull("failed to tokenize", tokens);
- Assert.assertEquals("failed to three token ", 3, tokens.length );
+ Assert.assertEquals("failed to three token ", 3, tokens.length);
+ }
+
+ @Test
+ public void encodeTest() {
+ String name = "ccsdkapps";
+ BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
+ String encodedValue = bCryptPasswordEncoder.encode(name);
+ Assert.assertTrue("Failed to match", bCryptPasswordEncoder.matches(name, encodedValue));
}
}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/test/resources/application.properties b/ms/controllerblueprints/application/src/test/resources/application.properties
index 5c6acf9..e812da5 100644
--- a/ms/controllerblueprints/application/src/test/resources/application.properties
+++ b/ms/controllerblueprints/application/src/test/resources/application.properties
@@ -20,6 +20,10 @@
ms_name=org.onap.ccsdk.apps.controllerblueprints
appVersion=1.0.0
+# Basic Authentication
+basic-auth.user-name=ccsdkapps
+basic-auth.hashed-pwd=$2a$10$MJxhNiOAffxbyrV9.rrOUewP9Q/ASg5Nit2cmP.yBaXGsVXo8BW3y
+
#To Remove Null in JSON API Response
spring.jackson.default-property-inclusion=non_null