Controller Blueprints Microservice 37/68337/1
authorMuthuramalingam, Brinda Santh(bs2796) <bs2796@att.com>
Fri, 21 Sep 2018 04:15:10 +0000 (04:15 +0000)
committerMuthuramalingam, Brinda Santh(bs2796) <bs2796@att.com>
Fri, 21 Sep 2018 04:15:10 +0000 (04:15 +0000)
Add basic authentication for Controllerblueprint MS.

Change-Id: I145e26d6feba873e8d3ed82e4169cbaa425a277e
Issue-ID: CCSDK-590
Signed-off-by: Muthuramalingam, Brinda Santh(bs2796) <bs2796@att.com>
ms/controllerblueprints/application/etc/logback.xml
ms/controllerblueprints/application/opt/app/onap/config/application.properties
ms/controllerblueprints/application/pom.xml
ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/ApplicationExceptionHandler.java
ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/filters/ApplicationLoggingFilter.java
ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/security/ApplicationBasicAuthenticationEntryPoint.java [new file with mode: 0644]
ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/security/ApplicationSecurityConfigurerAdapter.java [new file with mode: 0644]
ms/controllerblueprints/application/src/test/java/org/onap/ccsdk/apps/controllerblueprints/ControllerBluprintsApplicationTest.java
ms/controllerblueprints/application/src/test/java/org/onap/ccsdk/apps/controllerblueprints/VersionSplitTest.java
ms/controllerblueprints/application/src/test/resources/application.properties

index 0a75e60..6639705 100644 (file)
@@ -33,6 +33,7 @@
 \r
     <logger name="org.springframework" level="info"/>\r
     <logger name="org.springframework.web" level="info"/>\r
+    <logger name="org.springframework.security.web.authentication" level="warn"/>\r
     <logger name="org.hibernate" level="error"/>\r
     <logger name="org.onap.ccsdk.apps" level="info"/>\r
 \r
index d281482..e4457d0 100644 (file)
@@ -18,6 +18,10 @@ appName=ControllerBluePrints
 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
index 24f4deb..9834924 100644 (file)
             <groupId>org.onap.ccsdk.apps.controllerblueprints</groupId>\r
             <artifactId>service</artifactId>\r
         </dependency>\r
+        <dependency>\r
+            <groupId>org.springframework.boot</groupId>\r
+            <artifactId>spring-boot-starter-security</artifactId>\r
+        </dependency>\r
         <dependency>\r
             <groupId>org.springframework.boot</groupId>\r
             <artifactId>spring-boot-starter-actuator</artifactId>\r
             <artifactId>spring-boot-starter-test</artifactId>\r
             <scope>test</scope>\r
         </dependency>\r
+        <dependency>\r
+            <groupId>org.springframework.security</groupId>\r
+            <artifactId>spring-security-test</artifactId>\r
+            <scope>test</scope>\r
+        </dependency>\r
         <dependency>\r
             <groupId>org.jetbrains.kotlin</groupId>\r
             <artifactId>kotlin-test</artifactId>\r
index 6e9dcd7..78706d5 100644 (file)
@@ -23,13 +23,19 @@ import org.onap.ccsdk.apps.controllerblueprints.service.common.ErrorMessage;
 import org.springframework.http.HttpStatus;\r
 import org.springframework.http.ResponseEntity;\r
 import org.springframework.http.converter.HttpMessageNotReadableException;\r
+import org.springframework.security.authentication.BadCredentialsException;\r
+import org.springframework.security.web.csrf.InvalidCsrfTokenException;\r
 import org.springframework.web.HttpRequestMethodNotSupportedException;\r
 import org.springframework.web.bind.MethodArgumentNotValidException;\r
 import org.springframework.web.bind.annotation.ControllerAdvice;\r
 import org.springframework.web.bind.annotation.ExceptionHandler;\r
+import org.springframework.web.bind.annotation.ResponseStatus;\r
 import org.springframework.web.bind.annotation.RestController;\r
 import org.springframework.web.context.request.WebRequest;\r
 \r
+import javax.naming.AuthenticationException;\r
+import java.nio.file.AccessDeniedException;\r
+\r
 @ControllerAdvice\r
 @RestController\r
 @SuppressWarnings("unused")\r
@@ -43,6 +49,14 @@ public class ApplicationExceptionHandler {
         return new ResponseEntity<>(exceptionResponse, HttpStatus.INTERNAL_SERVER_ERROR);\r
     }\r
 \r
+    @ExceptionHandler({InvalidCsrfTokenException.class, AuthenticationException.class, BadCredentialsException.class, AccessDeniedException.class})\r
+    @ResponseStatus(value = HttpStatus.UNAUTHORIZED)\r
+    public final ResponseEntity<ErrorMessage> handleAuthenticationRequest(Exception ex, WebRequest request) {\r
+        log.error("Authentication Exception", ex);\r
+        ErrorMessage exceptionResponse = new ErrorMessage(ex.getMessage(), HttpStatus.UNAUTHORIZED.value(), ex.getLocalizedMessage());\r
+        return new ResponseEntity<>(exceptionResponse, HttpStatus.UNAUTHORIZED);\r
+    }\r
+\r
     @ExceptionHandler({HttpMessageNotReadableException.class, MethodArgumentNotValidException.class,\r
             HttpRequestMethodNotSupportedException.class})\r
     public final ResponseEntity<ErrorMessage> handleBadRequest(Exception ex, WebRequest request) {\r
index fbef55f..4476117 100644 (file)
@@ -25,6 +25,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;\r
 import org.slf4j.MDC;\r
 import org.springframework.beans.factory.annotation.Value;\r
+import org.springframework.core.Ordered;\r
+import org.springframework.core.annotation.Order;\r
 import org.springframework.stereotype.Component;\r
 \r
 import javax.servlet.*;\r
@@ -40,6 +42,7 @@ import java.io.IOException;
  */\r
 @Component\r
 @WebFilter(asyncSupported = true, urlPatterns = {"/*"})\r
+@Order(Ordered.HIGHEST_PRECEDENCE)\r
 @SuppressWarnings("unused")\r
 public class ApplicationLoggingFilter implements Filter {\r
     private static Logger log = LoggerFactory.getLogger(ApplicationLoggingFilter.class);\r
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 (file)
index 0000000..e3df3a6
--- /dev/null
@@ -0,0 +1,43 @@
+/*\r
+ *  Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ *  Licensed under the Apache License, Version 2.0 (the "License");\r
+ *  you may not use this file except in compliance with the License.\r
+ *  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *  Unless required by applicable law or agreed to in writing, software\r
+ *  distributed under the License is distributed on an "AS IS" BASIS,\r
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *  See the License for the specific language governing permissions and\r
+ *  limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.security;\r
+\r
+import org.springframework.security.core.AuthenticationException;\r
+import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;\r
+import org.springframework.stereotype.Component;\r
+import javax.servlet.http.HttpServletRequest;\r
+import javax.servlet.http.HttpServletResponse;\r
+import java.io.IOException;\r
+\r
+@Component\r
+public class ApplicationBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {\r
+\r
+    @Override\r
+    public void commence(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException authException)\r
+            throws IOException {\r
+        response.addHeader("WWW-Authenticate", "Basic realm=\"" + getRealmName() + "\"");\r
+        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);\r
+        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");\r
+    }\r
+\r
+    @Override\r
+    public void afterPropertiesSet() throws Exception {\r
+        setRealmName("CCSDK-APPS");\r
+        super.afterPropertiesSet();\r
+    }\r
+\r
+}
\ 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 (file)
index 0000000..3a39d78
--- /dev/null
@@ -0,0 +1,72 @@
+/*\r
+ *  Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ *  Licensed under the Apache License, Version 2.0 (the "License");\r
+ *  you may not use this file except in compliance with the License.\r
+ *  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *  Unless required by applicable law or agreed to in writing, software\r
+ *  distributed under the License is distributed on an "AS IS" BASIS,\r
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *  See the License for the specific language governing permissions and\r
+ *  limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.security;\r
+\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.beans.factory.annotation.Value;\r
+import org.springframework.context.annotation.Bean;\r
+import org.springframework.context.annotation.Configuration;\r
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;\r
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;\r
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;\r
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;\r
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;\r
+import org.springframework.security.crypto.password.PasswordEncoder;\r
+\r
+@SuppressWarnings("unused")\r
+@Configuration\r
+@EnableWebSecurity\r
+public class ApplicationSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {\r
+\r
+    @Value("${basic-auth.user-name}")\r
+    private String userName;\r
+\r
+    @Value("${basic-auth.hashed-pwd}")\r
+    private String userHashedPassword;\r
+\r
+    private static EELFLogger log = EELFManager.getInstance().getLogger(ApplicationSecurityConfigurerAdapter.class);\r
+\r
+    @Autowired\r
+    private ApplicationBasicAuthenticationEntryPoint authenticationEntryPoint;\r
+\r
+    @Autowired\r
+    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {\r
+        log.info("User Id {} and hashed pwd : {}", userName, userHashedPassword);\r
+        auth.inMemoryAuthentication()\r
+                .withUser(userName).password(userHashedPassword)\r
+                .authorities("ROLE_USER");\r
+    }\r
+\r
+    @Override\r
+    protected void configure(HttpSecurity http) throws Exception {\r
+        http.authorizeRequests()\r
+                .antMatchers("/actuator/health").permitAll()\r
+                .antMatchers("/**").authenticated()\r
+                .and()\r
+                .httpBasic()\r
+                .authenticationEntryPoint(authenticationEntryPoint);\r
+\r
+        http.csrf().disable();\r
+    }\r
+\r
+    @Bean\r
+    public PasswordEncoder passwordEncoder() {\r
+        return new BCryptPasswordEncoder();\r
+    }\r
+}
\ No newline at end of file
index 61b5c50..7a5f952 100644 (file)
@@ -1,6 +1,6 @@
 /*\r
  * Copyright © 2017-2018 AT&T Intellectual Property.\r
- * Modifications Copyright © 2018 IBM.\r
+ *\r
  * Licensed under the Apache License, Version 2.0 (the "License");\r
  * you may not use this file except in compliance with the License.\r
  * You may obtain a copy of the License at\r
@@ -16,8 +16,6 @@
 \r
 package org.onap.ccsdk.apps.controllerblueprints;\r
 \r
-import static org.assertj.core.api.Assertions.assertThat;\r
-\r
 import org.junit.Assert;\r
 import org.junit.Before;\r
 import org.junit.Test;\r
@@ -27,56 +25,40 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;\r
 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;\r
 import org.springframework.boot.test.web.client.TestRestTemplate;\r
-import org.springframework.http.HttpEntity;\r
-import org.springframework.http.HttpHeaders;\r
-import org.springframework.http.HttpMethod;\r
-import org.springframework.http.HttpStatus;\r
-import org.springframework.http.MediaType;\r
-import org.springframework.http.ResponseEntity;\r
+import org.springframework.http.*;\r
+import org.springframework.http.client.support.BasicAuthorizationInterceptor;\r
 import org.springframework.test.context.junit4.SpringRunner;\r
 \r
-import com.att.eelf.configuration.EELFLogger;\r
-import com.att.eelf.configuration.EELFManager;\r
+import static org.assertj.core.api.Assertions.assertThat;\r
 \r
 @RunWith(SpringRunner.class)\r
 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)\r
 public class ControllerBluprintsApplicationTest {\r
-    private static EELFLogger log = EELFManager.getInstance().getLogger(ControllerBluprintsApplicationTest.class);\r
-\r
     @Autowired\r
     private TestRestTemplate restTemplate;\r
-    private HttpHeaders headers;\r
-    private ResponseEntity<ConfigModel> entity;\r
 \r
     @Before\r
     public void setUp(){\r
-        headers = new HttpHeaders();\r
-        headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);\r
-        entity = this.restTemplate\r
-                .exchange("/api/v1/config-model/1", HttpMethod.GET, new HttpEntity<>(headers),ConfigModel.class);\r
-        \r
+        BasicAuthorizationInterceptor bai = new BasicAuthorizationInterceptor("ccsdkapps", "ccsdkapps");\r
+        this.restTemplate.getRestTemplate().getInterceptors().add(bai);\r
     }\r
 \r
     @Test\r
     public void testConfigModel() {\r
-\r
         HttpHeaders headers = new HttpHeaders();\r
         headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);\r
         ResponseEntity<ConfigModel> entity = this.restTemplate\r
                 .exchange("/api/v1/config-model/1", HttpMethod.GET, new HttpEntity<>(headers),ConfigModel.class);\r
-\r
         assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);\r
         Assert.assertNotNull("failed to get response Config model",entity.getBody());\r
     }\r
 \r
     @Test\r
     public void testConfigModelFailure() {\r
-\r
         HttpHeaders headers = new HttpHeaders();\r
         headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);\r
         ResponseEntity<ConfigModel> entity = this.restTemplate\r
                 .exchange("/api/v1/config-model-not-found/1", HttpMethod.GET, new HttpEntity<>(headers),ConfigModel.class);\r
-\r
         assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);\r
         Assert.assertNotNull("failed to get response Config model",entity.getBody());\r
     }\r
index 9445e1d..995644f 100644 (file)
 \r
 package org.onap.ccsdk.apps.controllerblueprints;\r
 \r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
 import org.apache.commons.lang3.StringUtils;\r
 import org.junit.Assert;\r
 import org.junit.Test;\r
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;\r
+\r
 /**\r
  * VersionSplitTest\r
  *\r
  * @author Brinda Santh\r
  */\r
 public class VersionSplitTest {\r
+    private static EELFLogger log = EELFManager.getInstance().getLogger(VersionSplitTest.class);\r
 \r
     @Test\r
     public void testVersionSplit() {\r
         String version = "1.03.04";\r
         String[] tokens = StringUtils.split(version, '.');\r
         Assert.assertNotNull("failed to tokenize", tokens);\r
-        Assert.assertEquals("failed to three token ", 3, tokens.length );\r
+        Assert.assertEquals("failed to three token ", 3, tokens.length);\r
+    }\r
+\r
+    @Test\r
+    public void encodeTest() {\r
+        String name = "ccsdkapps";\r
+        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();\r
+        String encodedValue = bCryptPasswordEncoder.encode(name);\r
+        Assert.assertTrue("Failed to match", bCryptPasswordEncoder.matches(name, encodedValue));\r
     }\r
 }
\ No newline at end of file
index 5c6acf9..e812da5 100644 (file)
@@ -20,6 +20,10 @@ appName=ControllerBluePrints
 ms_name=org.onap.ccsdk.apps.controllerblueprints\r
 appVersion=1.0.0\r
 \r
+# Basic Authentication\r
+basic-auth.user-name=ccsdkapps\r
+basic-auth.hashed-pwd=$2a$10$MJxhNiOAffxbyrV9.rrOUewP9Q/ASg5Nit2cmP.yBaXGsVXo8BW3y\r
+\r
 #To Remove Null in JSON API Response\r
 spring.jackson.default-property-inclusion=non_null\r
 \r