Add basic authentication for Controllerblueprint MS.
Change-Id: I145e26d6feba873e8d3ed82e4169cbaa425a277e
Issue-ID: CCSDK-590
Signed-off-by: Muthuramalingam, Brinda Santh(bs2796) <bs2796@att.com>
\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
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
<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
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
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
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
*/\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
/*\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
\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
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
\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
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