From 0f2c2039cd9d9b26482fc7488ae1bdf99f2544f5 Mon Sep 17 00:00:00 2001 From: Zlatko Murgoski Date: Tue, 5 Mar 2019 11:31:48 +0100 Subject: Collector authentication enhancement Collector authentication enhancement Change-Id: I03a05cb83dd8c498fb218e82e9b3958348fbb4ac Issue-ID: DCAEGEN2-1101 Signed-off-by: Zlatko Murgoski --- README.md | 20 ++-- dpo/blueprint/blueprint_ves.yaml | 2 +- dpo/spec/vescollector-componentspec.json | 16 +-- dpo/tosca_model/schema.yaml | 2 +- dpo/tosca_model/template.yaml | 2 +- dpo/tosca_model/translate.yaml | 6 +- etc/collector.properties | 39 +++---- pom.xml | 2 +- .../java/org/onap/dcae/ApplicationSettings.java | 13 +-- .../org/onap/dcae/common/SSLContextCreator.java | 10 +- .../onap/dcae/common/configuration/AuthMethod.java | 26 +++++ .../dcae/common/configuration/AuthMethodType.java | 37 +++++++ .../onap/dcae/common/configuration/BasicAuth.java | 48 +++++++++ .../onap/dcae/common/configuration/CertAuth.java | 49 +++++++++ .../dcae/common/configuration/CertBasicAuth.java | 50 +++++++++ .../org/onap/dcae/common/configuration/NoAuth.java | 62 +++++++++++ .../common/configuration/SslContextCreator.java | 116 +++++++++++++++++++++ .../org/onap/dcae/restapi/ApiAuthInterceptor.java | 37 +++++-- .../java/org/onap/dcae/restapi/ServletConfig.java | 112 ++++---------------- .../org/onap/dcae/ApplicationSettingsTest.java | 14 +-- src/test/java/org/onap/dcae/TLSTest.java | 15 +-- .../onap/dcae/restapi/ApiAuthInterceptionTest.java | 17 +-- src/test/resources/controller-config_dmaap_ip.json | 2 +- .../resources/controller-config_singleline_ip.json | 2 +- src/test/resources/test_collector_ip_op.properties | 2 +- src/test/resources/testcollector.properties | 2 +- version.properties | 2 +- 27 files changed, 509 insertions(+), 196 deletions(-) create mode 100644 src/main/java/org/onap/dcae/common/configuration/AuthMethod.java create mode 100644 src/main/java/org/onap/dcae/common/configuration/AuthMethodType.java create mode 100644 src/main/java/org/onap/dcae/common/configuration/BasicAuth.java create mode 100644 src/main/java/org/onap/dcae/common/configuration/CertAuth.java create mode 100644 src/main/java/org/onap/dcae/common/configuration/CertBasicAuth.java create mode 100644 src/main/java/org/onap/dcae/common/configuration/NoAuth.java create mode 100644 src/main/java/org/onap/dcae/common/configuration/SslContextCreator.java diff --git a/README.md b/README.md index 7bdd993a..2193d3e9 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ For R1 as only measurement and faults are expected in ONAP, configuration are pr ``` STEPS FOR SETUP/TEST 1) Get the VESCollector image from Nexus - docker pull nexus.onap.org:10001/onap/org.onap.dcaegen2.collectors.ves.vescollector:1.1 + docker pull nexus.onap.org:10001/onap/org.onap.dcaegen2.collectors.ves.vescollector:latest 2) Start the container (change the DMAAPHOST environment value to running DMAAP instance host) docker run -d -p 8080:8080/tcp -p 8443:8443/tcp -P -e DMAAPHOST='10.0.0.174' nexus.onap.org:10001/onap/org.onap.dcaegen2.collectors.ves.vescollector:1.1 3) Login into container and tail /opt/app/VESCollector/logs/collector.log @@ -122,14 +122,14 @@ STEPS FOR SETUP/TEST 6) When test is done – do ensure to remove the container (docker rm -f ) to avoid port conflict ``` -Authentication is disabled on the container by default; below are the steps for enabling HTTPS/authentication for VESCollector. +Authentication is set by default to "noauth" (via auth.method property) on the container; below are the steps for enabling HTTPS/authentication for VESCollector. ``` 1) Login to the container 2) Open /opt/app/VESCollector/etc/collector.properties and edit below properties a) Comment below property (with authentication enabled, standard http should be disabled) collector.service.port=8080 - b) Enable basic-authentication - header.authflag=1 + b) Enable basic-authentication + auth.method=basicAuth Note: The actual credentials is stored part of header.authlist parameter. This is list of userid,password values. Default configuration has below set sample1,$2a$10$pgjaxDzSuc6XVFEeqvxQ5u90DKJnM/u7TJTcinAlFJVaavXMWf/Zi|vdnsagg,$2a$10$C45JhiRSY.qXTBfzWST3Q.AmwKlPRMc67c33O0U9hOH8KSGaweN4m where password maps to same value as username. @@ -137,10 +137,10 @@ Authentication is disabled on the container by default; below are the steps for 3) Restart the collector cd /opt/app/VESCollector ./bin/appController.sh stop - ./bin/appController.sh start + ./bin/appController.sh start 4) Exit from container and ensure tcp port on VM is not hanging on finwait – you can execute “netstat -an | grep 8443” . If under FIN_WAIT2, wait for server to release. -5) Simulate via curl (Note - username/pwd will be required) - Example of successfull POST: +5) Simulate via curl (Note - username/pwd will be required) + Example of successfull POST: vv770d@osdcae-dev-16:~$ curl -i -u 'sample1:sample1' -X POST -d @volte.txt --header "Content-Type: application/json" https://localhost:8443/eventListener/v5 -k HTTP/1.1 200 OK Server: Apache-Coyote/1.1 @@ -170,8 +170,10 @@ A client's certificate verification is disabled on the container by default; bel 2) Open /opt/app/VESCollector/etc/collector.properties and edit below properties a) Comment below property (with authentication enabled, standard http should be disabled) collector.service.port=8080 - b) Enable a client's certificate verification - collector.service.secure.clientauth=1 + b) Enable a client's certificate verification + auth.method=certOnly (only certificate verification) + or + auth.method=certBasicAuth ( certificate verification with basic auth verification ) 3) Restart the collector cd /opt/app/VESCollector ./bin/appController.sh stop diff --git a/dpo/blueprint/blueprint_ves.yaml b/dpo/blueprint/blueprint_ves.yaml index 3785593b..2dbc5a66 100644 --- a/dpo/blueprint/blueprint_ves.yaml +++ b/dpo/blueprint/blueprint_ves.yaml @@ -100,7 +100,7 @@ node_templates: collector.service.secure.port: -1 tomcat.maxthreads: '200' collector.keystore.file.location: "/opt/app/dcae-certificate/keystore.jks" - header.authflag: 0 + auth.method: "noAuth" collector.service.port: 8080 streams_publishes: sec_fault_unsecure: diff --git a/dpo/spec/vescollector-componentspec.json b/dpo/spec/vescollector-componentspec.json index 9e29c2cd..4e2eb970 100644 --- a/dpo/spec/vescollector-componentspec.json +++ b/dpo/spec/vescollector-componentspec.json @@ -234,8 +234,8 @@ "parameters": [ { "name": "collector.service.port", - "value": -1, - "description": "standard http port collector will open for listening; this will be disabled when header.authflag is set to 1", + "value": 8080, + "description": "standard http port collector will open for listening;", "sourced_at_deployment": false, "policy_editable": false, "designer_editable": false @@ -248,14 +248,6 @@ "policy_editable": false, "designer_editable": true }, - { - "name": "collector.service.secure.clientauth", - "value": 0, - "description": "Mutual TLS authentication flag; enables an authentication of the client to the server", - "sourced_at_deployment": false, - "policy_editable": false, - "designer_editable": false - }, { "name": "collector.keystore.file.location", "value": "/opt/app/dcae-certificate/keystore.jks", @@ -305,8 +297,8 @@ "designer_editable": false }, { - "name": "header.authflag", - "value": 1, + "name": "auth.method", + "value": "noAuth", "description": "Basic Authentication flag; when enabled only secure port will be supported.", "sourced_at_deployment": false, "policy_editable": false, diff --git a/dpo/tosca_model/schema.yaml b/dpo/tosca_model/schema.yaml index 6182761b..6c1b2757 100644 --- a/dpo/tosca_model/schema.yaml +++ b/dpo/tosca_model/schema.yaml @@ -209,7 +209,7 @@ node_types: type: string docker_collector.service.secure.port: type: string - docker_header.authflag: + docker_auth.method: type: string docker_header.authlist: type: string diff --git a/dpo/tosca_model/template.yaml b/dpo/tosca_model/template.yaml index ce0da721..73b4ad38 100644 --- a/dpo/tosca_model/template.yaml +++ b/dpo/tosca_model/template.yaml @@ -33,7 +33,7 @@ topology_template: docker_collector.schema.file: ./etc/CommonEventFormat_27.2.json docker_collector.service.port: '8080' docker_collector.service.secure.port: '-1' - docker_header.authflag: '0' + docker_auth.method: noAuth docker_header.authlist: userid1,base64encodepwd1|userid2,base64encodepwd2 docker_tomcat.maxthreads: '200' location_id: diff --git a/dpo/tosca_model/translate.yaml b/dpo/tosca_model/translate.yaml index 2de809b6..284f34bf 100644 --- a/dpo/tosca_model/translate.yaml +++ b/dpo/tosca_model/translate.yaml @@ -38,7 +38,7 @@ topology_template: type: string docker_collector.service.secure.port: type: string - docker_header.authflag: + docker_auth.method: type: string docker_header.authlist: type: string @@ -119,8 +119,8 @@ topology_template: get_input: docker_collector.service.port collector.service.secure.port: get_input: docker_collector.service.secure.port - header.authflag: - get_input: docker_header.authflag + auth.method: + get_input: docker_auth.method header.authlist: get_input: docker_header.authlist tomcat.maxthreads: diff --git a/etc/collector.properties b/etc/collector.properties index f0aac3b5..36c79b51 100755 --- a/etc/collector.properties +++ b/etc/collector.properties @@ -11,19 +11,30 @@ ## Normally: ## ## - 8080 is http service -## - https is disabled by default (-1) +## - https is disabled by default ## ## - At this time, the server always binds to 0.0.0.0 ## -## The default port when header.authflag is disabled (0) +## collector.service.port=8080 -## The secure port is required if header.authflag is set to 1 (true) ## Authentication is only supported via secure port ## When enabled - require valid keystore defined collector.service.secure.port=8443 -collector.service.secure.clientauth=0 +# auth.method flags: +# +# noAuth - default option - no security (http) +# certOnly - auth by certificate (https) +# basicAuth - auth by basic auth username and password (https) +# certBasicAuth - auth by certificate and basic auth username / password (https) +auth.method=noAuth + +## Combination of userid,hashPassword encoded pwd list to be supported +## userid and pwd comma separated; pipe delimitation between each pair +## Password is generated by crypt-password library using BCrypt algorithm stored in dcaegen2/sdk package +## or https://nexus.onap.org/#nexus-search;quick~crypt-password +header.authlist=sample1,$2a$10$0buh.2WeYwN868YMwnNNEuNEAMNYVU9.FSMJGyIKV3dGET/7oGOi6 ## The keystore must be setup per installation when secure port is configured collector.keystore.file.location=etc/keystore @@ -33,7 +44,6 @@ collector.keystore.passwordfile=etc/passwordfile collector.truststore.file.location=etc/truststore collector.truststore.passwordfile=etc/trustpasswordfile -############################################################################### ## Processing ## ## If there's a problem that prevents the collector from processing alarms, @@ -53,27 +63,10 @@ collector.schema.file={\"v1\":\"./etc/CommonEventFormat_27.2.json\",\"v2\":\"./e collector.dmaap.streamid=fault=ves-fault|syslog=ves-syslog|heartbeat=ves-heartbeat|measurementsForVfScaling=ves-measurement|mobileFlow=ves-mobileflow|other=ves-other|stateChange=ves-statechange|thresholdCrossingAlert=ves-thresholdCrossingAlert|voiceQuality=ves-voicequality|sipSignaling=ves-sipsignaling|notification=ves-notification|pnfRegistration=ves-pnfRegistration collector.dmaapfile=./etc/DmaapConfig.json -## authflag control authentication by the collector -## If enabled (1) - then authlist has to be defined -## When authflag is enabled, only secure port will be supported -## To disable enter 0 -header.authflag=0 - -## Combination of userid,hashPassword encoded pwd list to be supported -## userid and pwd comma separated; pipe delimitation between each pair -header.authlist=sample1,$2a$10$0buh.2WeYwN868YMwnNNEuNEAMNYVU9.FSMJGyIKV3dGET/7oGOi6 - ## Event transformation Flag - when set expects configurable transformation ## defined under ./etc/eventTransform.json ## Enabled by default; to disable set to 0 event.transform.flag=1 # Describes at what frequency (measured in minutes) should application try to fetch config from CBS -collector.dynamic.config.update.frequency=5 - -############################################################################### -## -## Tomcat control -## -#tomcat.maxthreads=(tomcat default, which is usually 200) - +collector.dynamic.config.update.frequency=5 \ No newline at end of file diff --git a/pom.xml b/pom.xml index cf3c5ffc..332324a7 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ org.onap.dcaegen2.collectors.ves VESCollector - 1.4.2-SNAPSHOT + 1.4.3-SNAPSHOT dcaegen2-collectors-ves VESCollector diff --git a/src/main/java/org/onap/dcae/ApplicationSettings.java b/src/main/java/org/onap/dcae/ApplicationSettings.java index 7a2bff97..c4f2c063 100644 --- a/src/main/java/org/onap/dcae/ApplicationSettings.java +++ b/src/main/java/org/onap/dcae/ApplicationSettings.java @@ -43,6 +43,7 @@ import javax.annotation.Nullable; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import org.json.JSONObject; +import org.onap.dcae.common.configuration.AuthMethodType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -119,10 +120,6 @@ public class ApplicationSettings { return properties.getInt("collector.schema.checkflag", -1) > 0; } - public boolean authorizationEnabled() { - return properties.getInt("header.authflag", 0) > 0; - } - public JsonSchema jsonSchema(String version) { return loadedJsonSchemas.get(version) .orElse(loadedJsonSchemas.get(FALLBACK_VES_VERSION)) @@ -175,10 +172,6 @@ public class ApplicationSettings { return prependWithUserDirOnRelative(properties.getString("collector.keystore.file.location", "etc/keystore")); } - public boolean clientTlsAuthenticationEnabled() { - return httpsEnabled() && properties.getInt("collector.service.secure.clientauth", 0) > 0; - } - public String truststorePasswordFileLocation() { return prependWithUserDirOnRelative(properties.getString("collector.truststore.passwordfile", "etc/trustpasswordfile")); } @@ -195,6 +188,10 @@ public class ApplicationSettings { return prependWithUserDirOnRelative(properties.getString("collector.dmaapfile", "etc/DmaapConfig.json")); } + public String authMethod(){ + return properties.getString("auth.method", AuthMethodType.NO_AUTH.value()); + } + public Map dMaaPStreamsMapping() { String streamIdsProperty = properties.getString("collector.dmaap.streamid", null); if (streamIdsProperty == null) { diff --git a/src/main/java/org/onap/dcae/common/SSLContextCreator.java b/src/main/java/org/onap/dcae/common/SSLContextCreator.java index e636f4c0..898e5d55 100644 --- a/src/main/java/org/onap/dcae/common/SSLContextCreator.java +++ b/src/main/java/org/onap/dcae/common/SSLContextCreator.java @@ -22,6 +22,7 @@ package org.onap.dcae.common; import java.nio.file.Path; import org.springframework.boot.web.server.Ssl; +import org.springframework.boot.web.server.Ssl.ClientAuth; public class SSLContextCreator { private final String keyStorePassword; @@ -31,6 +32,7 @@ public class SSLContextCreator { private Path trustStoreFile; private String trustStorePassword; private boolean hasTlsClientAuthentication = false; + private ClientAuth clientAuth; public static SSLContextCreator create(final Path keyStoreFile, final String certAlias, final String password) { return new SSLContextCreator(keyStoreFile, certAlias, password); @@ -42,8 +44,9 @@ public class SSLContextCreator { this.keyStorePassword = password; } - public SSLContextCreator withTlsClientAuthentication(final Path trustStoreFile, final String password) { - hasTlsClientAuthentication = true; + public SSLContextCreator withTlsClientAuthentication(final Path trustStoreFile, final String password, final ClientAuth clientAuth) { + this.clientAuth = clientAuth; + this.hasTlsClientAuthentication = true; this.trustStoreFile = trustStoreFile; this.trustStorePassword = password; @@ -62,7 +65,7 @@ public class SSLContextCreator { ssl.setTrustStore(trustStore); ssl.setTrustStorePassword(trustStorePassword); - ssl.setClientAuth(Ssl.ClientAuth.NEED); + ssl.setClientAuth(clientAuth); } public Ssl build() { @@ -74,7 +77,6 @@ public class SSLContextCreator { if (hasTlsClientAuthentication) { configureTrustStore(ssl); } - return ssl; } } \ No newline at end of file diff --git a/src/main/java/org/onap/dcae/common/configuration/AuthMethod.java b/src/main/java/org/onap/dcae/common/configuration/AuthMethod.java new file mode 100644 index 00000000..21614856 --- /dev/null +++ b/src/main/java/org/onap/dcae/common/configuration/AuthMethod.java @@ -0,0 +1,26 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018 Nokia. All rights reserved.s + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.dcae.common.configuration; + +public interface AuthMethod { + void configure(); +} diff --git a/src/main/java/org/onap/dcae/common/configuration/AuthMethodType.java b/src/main/java/org/onap/dcae/common/configuration/AuthMethodType.java new file mode 100644 index 00000000..7eb1b414 --- /dev/null +++ b/src/main/java/org/onap/dcae/common/configuration/AuthMethodType.java @@ -0,0 +1,37 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018 Nokia. All rights reserved.s + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.dcae.common.configuration; + +public enum AuthMethodType { + + NO_AUTH("noAuth"),CERT_ONLY("certOnly"),CERT_BASIC_AUTH("certBasicAuth"),BASIC_AUTH("basicAuth"); + + private final String value; + + AuthMethodType(String value) { + this.value = value; + } + + public String value() { + return value; + } +} diff --git a/src/main/java/org/onap/dcae/common/configuration/BasicAuth.java b/src/main/java/org/onap/dcae/common/configuration/BasicAuth.java new file mode 100644 index 00000000..c3730512 --- /dev/null +++ b/src/main/java/org/onap/dcae/common/configuration/BasicAuth.java @@ -0,0 +1,48 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018 Nokia. All rights reserved.s + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.dcae.common.configuration; + +import org.onap.dcae.ApplicationSettings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; + +public class BasicAuth implements AuthMethod { + + private static final Logger log = LoggerFactory.getLogger(BasicAuth.class); + private final ConfigurableServletWebServerFactory container; + private final ApplicationSettings properties; + + public BasicAuth(ConfigurableServletWebServerFactory container, ApplicationSettings properties) { + this.container = container; + this.properties = properties; + } + + @Override + public void configure() { + SslContextCreator sslContextCreator = new SslContextCreator(properties); + container.setPort(properties.httpsPort()); + container.setSsl(sslContextCreator.simpleHttpsContext()); + log.info(String.format("Application work in %s mode on %s port.", + properties.authMethod(), properties.httpsPort())); + } +} diff --git a/src/main/java/org/onap/dcae/common/configuration/CertAuth.java b/src/main/java/org/onap/dcae/common/configuration/CertAuth.java new file mode 100644 index 00000000..3c4fb62c --- /dev/null +++ b/src/main/java/org/onap/dcae/common/configuration/CertAuth.java @@ -0,0 +1,49 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018 Nokia. All rights reserved.s + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.dcae.common.configuration; + +import org.onap.dcae.ApplicationSettings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.web.server.Ssl.ClientAuth; +import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; + +public class CertAuth implements AuthMethod { + + private static final Logger log = LoggerFactory.getLogger(CertAuth.class); + private final ConfigurableServletWebServerFactory container; + private final ApplicationSettings properties; + + public CertAuth(ConfigurableServletWebServerFactory container, ApplicationSettings properties) { + this.container = container; + this.properties = properties; + } + + @Override + public void configure() { + SslContextCreator sslContextCreator = new SslContextCreator(properties); + container.setSsl(sslContextCreator.httpsContextWithTlsAuthentication(ClientAuth.NEED)); + container.setPort(properties.httpsPort()); + log.info(String.format("Application work in %s mode on %s port.", + properties.authMethod(), properties.httpsPort())); + } +} diff --git a/src/main/java/org/onap/dcae/common/configuration/CertBasicAuth.java b/src/main/java/org/onap/dcae/common/configuration/CertBasicAuth.java new file mode 100644 index 00000000..f756b47d --- /dev/null +++ b/src/main/java/org/onap/dcae/common/configuration/CertBasicAuth.java @@ -0,0 +1,50 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018 Nokia. All rights reserved.s + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.dcae.common.configuration; + +import org.onap.dcae.ApplicationSettings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.web.server.Ssl.ClientAuth; +import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; + +public class CertBasicAuth implements AuthMethod{ + + private static final Logger log = LoggerFactory.getLogger(CertAuth.class); + private final ConfigurableServletWebServerFactory container; + private final ApplicationSettings properties; + + public CertBasicAuth(ConfigurableServletWebServerFactory container, ApplicationSettings properties) { + this.container = container; + this.properties = properties; + } + + @Override + public void configure() { + SslContextCreator sslContextCreator = new SslContextCreator(properties); + container.setPort(properties.httpsPort()); + container.setSsl(sslContextCreator.httpsContextWithTlsAuthentication(ClientAuth.WANT)); + log.info(String.format("Application work in %s mode on %s port.", + properties.authMethod(), properties.httpsPort())); + } +} + diff --git a/src/main/java/org/onap/dcae/common/configuration/NoAuth.java b/src/main/java/org/onap/dcae/common/configuration/NoAuth.java new file mode 100644 index 00000000..a64749c0 --- /dev/null +++ b/src/main/java/org/onap/dcae/common/configuration/NoAuth.java @@ -0,0 +1,62 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018 Nokia. All rights reserved.s + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.dcae.common.configuration; + +import org.onap.dcae.ApplicationSettings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; + +public class NoAuth implements AuthMethod { + + private static final Logger log = LoggerFactory.getLogger(NoAuth.class); + + private final ConfigurableServletWebServerFactory container; + private final ApplicationSettings properties; + + public NoAuth(ConfigurableServletWebServerFactory container, ApplicationSettings properties) { + this.container = container; + this.properties = properties; + } + + @Override + public void configure() { + if (validateAuthMethod()){ + container.setPort(properties.httpsPort()); + logContainerConfiguration(properties.httpsPort()); + } + else { + container.setPort(properties.httpPort()); + logContainerConfiguration(properties.httpPort()); + } + } + + private boolean validateAuthMethod() { + return properties.authMethod().equalsIgnoreCase(AuthMethodType.BASIC_AUTH.value()) + || properties.authMethod().equalsIgnoreCase(AuthMethodType.CERT_ONLY.value()) + || properties.authMethod().equalsIgnoreCase(AuthMethodType.CERT_BASIC_AUTH.value()); + } + + private void logContainerConfiguration(int port) { + log.info(String.format("Application work in %s mode on %s port.", properties.authMethod(), port)); + } +} diff --git a/src/main/java/org/onap/dcae/common/configuration/SslContextCreator.java b/src/main/java/org/onap/dcae/common/configuration/SslContextCreator.java new file mode 100644 index 00000000..f0e470be --- /dev/null +++ b/src/main/java/org/onap/dcae/common/configuration/SslContextCreator.java @@ -0,0 +1,116 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018 Nokia. All rights reserved.s + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.dcae.common.configuration; + +import static java.nio.file.Files.readAllBytes; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import org.onap.dcae.ApplicationException; +import org.onap.dcae.ApplicationSettings; +import org.onap.dcae.common.SSLContextCreator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.web.server.Ssl; +import org.springframework.boot.web.server.Ssl.ClientAuth; + +public class SslContextCreator { + + private static final Logger log = LoggerFactory.getLogger(CertAuth.class); + private final ApplicationSettings properties; + + public SslContextCreator(ApplicationSettings properties) { + this.properties = properties; + } + + public Ssl httpsContextWithTlsAuthentication(ClientAuth clientAuth) { + final SSLContextCreator sslContextCreator = simpleHttpsContextBuilder(); + + log.info("Enabling TLS client authorization"); + + final Path trustStore = toAbsolutePath(properties.truststoreFileLocation()); + log.info("Using trustStore path: " + trustStore); + + final Path trustPasswordFileLocation = toAbsolutePath(properties.truststorePasswordFileLocation()); + final String trustStorePassword = getKeyStorePassword(trustPasswordFileLocation); + log.info("Using trustStore password from: " + trustPasswordFileLocation); + + return sslContextCreator.withTlsClientAuthentication(trustStore, trustStorePassword, clientAuth).build(); + } + + public Ssl simpleHttpsContext(){ + return simpleHttpsContextBuilder().build(); + } + + private SSLContextCreator simpleHttpsContextBuilder() { + log.info("Enabling SSL"); + + final Path keyStorePath = toAbsolutePath(properties.keystoreFileLocation()); + log.info("Using keyStore path: " + keyStorePath); + + final Path keyStorePasswordLocation = toAbsolutePath(properties.keystorePasswordFileLocation()); + final String keyStorePassword = getKeyStorePassword(keyStorePasswordLocation); + log.info("Using keyStore password from: " + keyStorePasswordLocation); + return SSLContextCreator.create(keyStorePath, getKeyStoreAlias(keyStorePath, keyStorePassword), keyStorePassword); + } + + private String getKeyStoreAlias(Path keyStorePath, String keyStorePassword) { + KeyStore keyStore = getKeyStore(); + try(InputStream keyStoreData = new FileInputStream(keyStorePath.toString())){ + keyStore.load(keyStoreData, keyStorePassword.toCharArray()); + String alias = keyStore.aliases().nextElement(); + log.info("Actual key store alias is: " + alias); + return alias; + } catch (IOException | GeneralSecurityException ex) { + log.error("Cannot load Key Store alias cause: " + ex); + throw new ApplicationException(ex); + } + } + + private KeyStore getKeyStore() { + try { + return KeyStore.getInstance(KeyStore.getDefaultType()); + } catch (KeyStoreException ex) { + log.error("Cannot create Key Store instance cause: " + ex); + throw new ApplicationException(ex); + } + } + + private Path toAbsolutePath(final String path) { + return Paths.get(path).toAbsolutePath(); + } + + private String getKeyStorePassword(final Path location) { + try { + return new String(readAllBytes(location)); + } catch (IOException e) { + log.error("Could not read keystore password from: '" + location + "'.", e); + throw new ApplicationException(e); + } + } +} diff --git a/src/main/java/org/onap/dcae/restapi/ApiAuthInterceptor.java b/src/main/java/org/onap/dcae/restapi/ApiAuthInterceptor.java index 3b76ae46..e2ac74c7 100644 --- a/src/main/java/org/onap/dcae/restapi/ApiAuthInterceptor.java +++ b/src/main/java/org/onap/dcae/restapi/ApiAuthInterceptor.java @@ -25,6 +25,7 @@ import java.util.Base64; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.onap.dcae.ApplicationSettings; +import org.onap.dcae.common.configuration.AuthMethodType; import org.onap.dcaegen2.services.sdk.security.CryptPassword; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,37 +35,51 @@ final class ApiAuthInterceptor extends HandlerInterceptorAdapter { private static final Logger LOG = LoggerFactory.getLogger(ApiAuthInterceptor.class); private final CryptPassword cryptPassword = new CryptPassword(); - private final ApplicationSettings applicationSettings; + private final ApplicationSettings settings; + private Logger errorLogger; - private Logger errorLog; - ApiAuthInterceptor(ApplicationSettings applicationSettings, Logger errorLog) { - this.applicationSettings = applicationSettings; - this.errorLog = errorLog; + public ApiAuthInterceptor(ApplicationSettings applicationSettings, Logger errorLogger) { + this.settings = applicationSettings; + this.errorLogger = errorLogger; } @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, - Object handler) throws IOException { - if (applicationSettings.authorizationEnabled()) { + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws IOException { + + if(settings.authMethod().equalsIgnoreCase(AuthMethodType.CERT_BASIC_AUTH.value())){ + if (request.getAttribute("javax.servlet.request.X509Certificate") != null){ + LOG.info("Request is authorized by certificate "); + return true; + } + } + + if (isBasicAuth()) { String authorizationHeader = request.getHeader("Authorization"); if (authorizationHeader == null || !isAuthorized(authorizationHeader)) { - response.setStatus(400); - errorLog.error("EVENT_RECEIPT_FAILURE: Unauthorized user"); + response.setStatus(401); + errorLogger.error("EVENT_RECEIPT_FAILURE: Unauthorized user"); response.getWriter().write(ApiException.UNAUTHORIZED_USER.toJSON().toString()); return false; } + LOG.info("Request is authorized by basic auth"); } return true; } + private boolean isBasicAuth() { + return settings.authMethod().equalsIgnoreCase(AuthMethodType.BASIC_AUTH.value()) + || settings.authMethod().equalsIgnoreCase(AuthMethodType.CERT_BASIC_AUTH.value()); + } + private boolean isAuthorized(String authorizationHeader) { try { String encodedData = authorizationHeader.split(" ")[1]; String decodedData = new String(Base64.getDecoder().decode(encodedData)); String providedUser = decodedData.split(":")[0].trim(); String providedPassword = decodedData.split(":")[1].trim(); - Option maybeSavedPassword = applicationSettings.validAuthorizationCredentials().get(providedUser); + Option maybeSavedPassword = settings.validAuthorizationCredentials().get(providedUser); boolean userRegistered = maybeSavedPassword.isDefined(); return userRegistered && cryptPassword.matches(providedPassword,maybeSavedPassword.get()); } catch (Exception e) { diff --git a/src/main/java/org/onap/dcae/restapi/ServletConfig.java b/src/main/java/org/onap/dcae/restapi/ServletConfig.java index e66f3f1f..e68ddcdf 100644 --- a/src/main/java/org/onap/dcae/restapi/ServletConfig.java +++ b/src/main/java/org/onap/dcae/restapi/ServletConfig.java @@ -21,23 +21,17 @@ package org.onap.dcae.restapi; -import static java.nio.file.Files.readAllBytes; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.security.GeneralSecurityException; -import java.security.KeyStore; -import java.security.KeyStoreException; +import java.util.HashMap; +import java.util.Map; import org.onap.dcae.ApplicationException; import org.onap.dcae.ApplicationSettings; -import org.onap.dcae.common.SSLContextCreator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.onap.dcae.common.configuration.AuthMethod; +import org.onap.dcae.common.configuration.AuthMethodType; +import org.onap.dcae.common.configuration.BasicAuth; +import org.onap.dcae.common.configuration.CertAuth; +import org.onap.dcae.common.configuration.CertBasicAuth; +import org.onap.dcae.common.configuration.NoAuth; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.web.server.Ssl; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; import org.springframework.stereotype.Component; @@ -45,90 +39,28 @@ import org.springframework.stereotype.Component; @Component public class ServletConfig implements WebServerFactoryCustomizer { - private static final Logger log = LoggerFactory.getLogger(ServletConfig.class); - @Autowired private ApplicationSettings properties; @Override public void customize(ConfigurableServletWebServerFactory container) { - final boolean hasClientTlsAuthentication = properties.clientTlsAuthenticationEnabled(); - if (hasClientTlsAuthentication || properties.authorizationEnabled()) { - container.setSsl(hasClientTlsAuthentication ? httpsContextWithTlsAuthentication() : simpleHttpsContext()); - int port = properties.httpsPort(); - container.setPort(port); - log.info("Application https port: " + port); - } else { - int port = properties.httpPort(); - container.setPort(port); - log.info("Application http port: " + port); - } - - } - - private SSLContextCreator simpleHttpsContextBuilder() { - log.info("Enabling SSL"); - - final Path keyStorePath = toAbsolutePath(properties.keystoreFileLocation()); - log.info("Using keyStore path: " + keyStorePath); - - final Path keyStorePasswordLocation = toAbsolutePath(properties.keystorePasswordFileLocation()); - final String keyStorePassword = getKeyStorePassword(keyStorePasswordLocation); - log.info("Using keyStore password from: " + keyStorePasswordLocation); - return SSLContextCreator.create(keyStorePath, getKeyStoreAlias(keyStorePath, keyStorePassword), keyStorePassword); - } - - private String getKeyStoreAlias(Path keyStorePath, String keyStorePassword) { - KeyStore keyStore = getKeyStore(); - try(InputStream keyStoreData = new FileInputStream(keyStorePath.toString())){ - keyStore.load(keyStoreData, keyStorePassword.toCharArray()); - String alias = keyStore.aliases().nextElement(); - log.info("Actual key store alias is: " + alias); - return alias; - } catch (IOException | GeneralSecurityException ex) { - log.error("Cannot load Key Store alias cause: " + ex); - throw new ApplicationException(ex); - } - } - - private KeyStore getKeyStore() { - try { - return KeyStore.getInstance(KeyStore.getDefaultType()); - } catch (KeyStoreException ex) { - log.error("Cannot create Key Store instance cause: " + ex); - throw new ApplicationException(ex); - } - } - - private Ssl simpleHttpsContext() { - return simpleHttpsContextBuilder().build(); - } - - private Ssl httpsContextWithTlsAuthentication() { - final SSLContextCreator sslContextCreator = simpleHttpsContextBuilder(); - - log.info("Enabling TLS client authorization"); - - final Path trustStore = toAbsolutePath(properties.truststoreFileLocation()); - log.info("Using trustStore path: " + trustStore); - - final Path trustPasswordFileLocation = toAbsolutePath(properties.truststorePasswordFileLocation()); - final String trustStorePassword = getKeyStorePassword(trustPasswordFileLocation); - log.info("Using trustStore password from: " + trustPasswordFileLocation); - - return sslContextCreator.withTlsClientAuthentication(trustStore, trustStorePassword).build(); + provideAuthConfigurations(container).getOrDefault(properties.authMethod(), + notSupportedOperation()).configure(); } - private Path toAbsolutePath(final String path) { - return Paths.get(path).toAbsolutePath(); + private Map provideAuthConfigurations(ConfigurableServletWebServerFactory container) { + Map authMethods = new HashMap<>(); + authMethods.put(AuthMethodType.CERT_ONLY.value(), new CertAuth(container, properties)); + authMethods.put(AuthMethodType.BASIC_AUTH.value(), new BasicAuth(container, properties)); + authMethods.put(AuthMethodType.CERT_BASIC_AUTH.value(), new CertBasicAuth(container, properties)); + authMethods.put(AuthMethodType.NO_AUTH.value(), new NoAuth(container, properties)); + return authMethods; } - private String getKeyStorePassword(final Path location) { - try { - return new String(readAllBytes(location)); - } catch (IOException e) { - log.error("Could not read keystore password from: '" + location + "'.", e); - throw new ApplicationException(e); - } + private AuthMethod notSupportedOperation() { + return () -> { + throw new ApplicationException( + "Provided auth method not allowed: " + properties.authMethod()); + }; } } \ No newline at end of file diff --git a/src/test/java/org/onap/dcae/ApplicationSettingsTest.java b/src/test/java/org/onap/dcae/ApplicationSettingsTest.java index 646d3e52..60287aef 100644 --- a/src/test/java/org/onap/dcae/ApplicationSettingsTest.java +++ b/src/test/java/org/onap/dcae/ApplicationSettingsTest.java @@ -343,23 +343,13 @@ public class ApplicationSettingsTest { assertEquals(dmaapStreamID, HashMap.empty()); } - @Test - public void shouldReturnIfAuthorizationIsEnabled() throws IOException { - // when - boolean authorizationEnabled = fromTemporaryConfiguration("header.authflag=1") - .authorizationEnabled(); - - // then - assertTrue(authorizationEnabled); - } - @Test public void shouldAuthorizationBeDisabledByDefault() throws IOException { // when - boolean authorizationEnabled = fromTemporaryConfiguration().authorizationEnabled(); + boolean authorizationEnabled = fromTemporaryConfiguration().authMethod().contains("noAuth"); // then - assertFalse(authorizationEnabled); + assertTrue(authorizationEnabled); } @Test diff --git a/src/test/java/org/onap/dcae/TLSTest.java b/src/test/java/org/onap/dcae/TLSTest.java index e088df28..b1f90371 100644 --- a/src/test/java/org/onap/dcae/TLSTest.java +++ b/src/test/java/org/onap/dcae/TLSTest.java @@ -24,6 +24,7 @@ package org.onap.dcae; import io.vavr.collection.HashMap; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.onap.dcae.common.configuration.AuthMethodType; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; @@ -86,8 +87,8 @@ public class TLSTest extends TLSTestBase { class HttpsWithTLSAuthenticationAndBasicAuthTest extends TestClassBase { @Test - public void shouldHttpsRequestWithoutBasicAuthFail() { - assertThrows(Exception.class, this::makeHttpsRequestWithClientCert); + public void shouldHttpsRequestWithoutBasicAuthSucceed() { + assertEquals(HttpStatus.OK, makeHttpsRequestWithClientCert().getStatusCode()); } @Test @@ -100,6 +101,7 @@ public class TLSTest extends TLSTestBase { static class HttpConfiguration extends TLSTestBase.ConfigurationBase { @Override protected void configureSettings(ApplicationSettings settings) { + when(settings.authMethod()).thenReturn(AuthMethodType.NO_AUTH.value()); } } @@ -111,7 +113,7 @@ public class TLSTest extends TLSTestBase { protected void configureSettings(ApplicationSettings settings) { when(settings.keystoreFileLocation()).thenReturn(KEYSTORE.toString()); when(settings.keystorePasswordFileLocation()).thenReturn(KEYSTORE_PASSWORD_FILE.toString()); - when(settings.authorizationEnabled()).thenReturn(true); + when(settings.authMethod()).thenReturn(AuthMethodType.BASIC_AUTH.value()); when(settings.validAuthorizationCredentials()).thenReturn(HashMap.of(USERNAME, "$2a$10$51tDgG2VNLde5E173Ay/YO.Fq.aD.LR2Rp8pY3QAKriOSPswvGviy")); } } @@ -120,8 +122,7 @@ public class TLSTest extends TLSTestBase { @Override protected void configureSettings(ApplicationSettings settings) { super.configureSettings(settings); - when(settings.authorizationEnabled()).thenReturn(false); - when(settings.clientTlsAuthenticationEnabled()).thenReturn(true); + when(settings.authMethod()).thenReturn(AuthMethodType.CERT_ONLY.value()); when(settings.truststoreFileLocation()).thenReturn(TRUSTSTORE.toString()); when(settings.truststorePasswordFileLocation()).thenReturn(TRUSTSTORE_PASSWORD_FILE.toString()); } @@ -131,7 +132,7 @@ public class TLSTest extends TLSTestBase { @Override protected void configureSettings(ApplicationSettings settings) { super.configureSettings(settings); - when(settings.authorizationEnabled()).thenReturn(true); + when(settings.authMethod()).thenReturn(AuthMethodType.CERT_BASIC_AUTH.value()); } } -} +} \ No newline at end of file diff --git a/src/test/java/org/onap/dcae/restapi/ApiAuthInterceptionTest.java b/src/test/java/org/onap/dcae/restapi/ApiAuthInterceptionTest.java index 569fd969..a295046b 100644 --- a/src/test/java/org/onap/dcae/restapi/ApiAuthInterceptionTest.java +++ b/src/test/java/org/onap/dcae/restapi/ApiAuthInterceptionTest.java @@ -28,6 +28,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.onap.dcae.ApplicationSettings; +import org.onap.dcae.common.configuration.AuthMethodType; import org.slf4j.Logger; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -89,7 +90,7 @@ public class ApiAuthInterceptionTest { // given final HttpServletRequest request = createEmptyRequest(); - when(settings.authorizationEnabled()).thenReturn(false); + when(settings.authMethod()).thenReturn(AuthMethodType.NO_AUTH.value()); // when final boolean isAuthorized = sut.preHandle(request, response, obj); @@ -103,7 +104,7 @@ public class ApiAuthInterceptionTest { // given final HttpServletRequest request = createEmptyRequest(); - when(settings.authorizationEnabled()).thenReturn(true); + when(settings.authMethod()).thenReturn(AuthMethodType.BASIC_AUTH.value()); when(response.getWriter()).thenReturn(writer); // when @@ -113,7 +114,7 @@ public class ApiAuthInterceptionTest { // then assertFalse(isAuthorized); - verify(response).setStatus(HttpStatus.BAD_REQUEST.value()); + verify(response).setStatus(HttpStatus.UNAUTHORIZED.value()); verify(writer).write(ApiException.UNAUTHORIZED_USER.toJSON().toString()); } @@ -122,7 +123,7 @@ public class ApiAuthInterceptionTest { // given final HttpServletRequest request = createRequestWithAuthorizationHeader(); - when(settings.authorizationEnabled()).thenReturn(true); + when(settings.authMethod()).thenReturn(AuthMethodType.BASIC_AUTH.value()); when(response.getWriter()).thenReturn(writer); // when @@ -131,7 +132,7 @@ public class ApiAuthInterceptionTest { // then assertFalse(isAuthorized); - verify(response).setStatus(HttpStatus.BAD_REQUEST.value()); + verify(response).setStatus(HttpStatus.UNAUTHORIZED.value()); verify(writer).write(ApiException.UNAUTHORIZED_USER.toJSON().toString()); } @@ -139,7 +140,7 @@ public class ApiAuthInterceptionTest { public void shouldSucceed() throws IOException { // given final HttpServletRequest request = createRequestWithAuthorizationHeader(); - when(settings.authorizationEnabled()).thenReturn(true); + when(settings.authMethod()).thenReturn(AuthMethodType.CERT_ONLY.value()); when(settings.validAuthorizationCredentials()).thenReturn( HashMap.of(USERNAME, "$2a$10$BsZkEynNm/93wbAeeZuxJeu6IHRyQl4XReqDg2BtYOFDhUsz20.3G")); when(response.getWriter()).thenReturn(writer); @@ -160,7 +161,7 @@ public class ApiAuthInterceptionTest { .header(HttpHeaders.AUTHORIZATION, "FooBar") .buildRequest(null); - when(settings.authorizationEnabled()).thenReturn(true); + when(settings.authMethod()).thenReturn(AuthMethodType.BASIC_AUTH.value()); when(settings.validAuthorizationCredentials()).thenReturn(CREDENTIALS); when(response.getWriter()).thenReturn(writer); @@ -170,7 +171,7 @@ public class ApiAuthInterceptionTest { // then assertFalse(isAuthorized); - verify(response).setStatus(HttpStatus.BAD_REQUEST.value()); + verify(response).setStatus(HttpStatus.UNAUTHORIZED.value()); verify(writer).write(ApiException.UNAUTHORIZED_USER.toJSON().toString()); } } diff --git a/src/test/resources/controller-config_dmaap_ip.json b/src/test/resources/controller-config_dmaap_ip.json index f12a36fa..1cc6576b 100644 --- a/src/test/resources/controller-config_dmaap_ip.json +++ b/src/test/resources/controller-config_dmaap_ip.json @@ -1,5 +1,5 @@ { - "header.authflag": 1, + "auth.method": "noAuth", "collector.inputQueue.maxPending": 8096, "collector.schema.checkflag": 1, "collector.keystore.file.location": "/opt/app/dcae-certificate/keystore.jks", diff --git a/src/test/resources/controller-config_singleline_ip.json b/src/test/resources/controller-config_singleline_ip.json index 827138c7..c3a8d067 100644 --- a/src/test/resources/controller-config_singleline_ip.json +++ b/src/test/resources/controller-config_singleline_ip.json @@ -1,5 +1,5 @@ { - "header.authflag": "1", + "auth.method": "noAuth", "collector.schema.file": "{\"v1\": \"./etc/CommonEventFormat_27.2.json\", \"v2\": \"./etc/CommonEventFormat_27.2.json\", \"v3\": \"./etc/CommonEventFormat_27.2.json\", \"v4\": \"./etc/CommonEventFormat_27.2.json\", \"v5\": \"./etc/CommonEventFormat_28.4.json\"}", "collector.keystore.passwordfile": "/opt/app/dcae-certificate/.password", "tomcat.maxthreads": "200", diff --git a/src/test/resources/test_collector_ip_op.properties b/src/test/resources/test_collector_ip_op.properties index 1d1364bc..9450067a 100644 --- a/src/test/resources/test_collector_ip_op.properties +++ b/src/test/resources/test_collector_ip_op.properties @@ -6,7 +6,7 @@ collector.schema.checkflag=1 collector.schema.file={\"v1\":\"./etc/CommonEventFormat_27.2.json\",\"v2\":\"./etc/CommonEventFormat_27.2.json\",\"v3\":\"./etc/CommonEventFormat_27.2.json\",\"v4\":\"./etc/CommonEventFormat_27.2.json\",\"v5\":\"./etc/CommonEventFormat_28.4.json\"} collector.dmaap.streamid=fault=ves-fault,ves-fault-secondary|syslog=ves-syslog,ves-syslog-secondary|heartbeat=ves-heartbeat,ves-heartbeat-secondary|measurementsForVfScaling=ves-measurement,ves-measurement-secondary|mobileFlow=ves-mobileflow,ves-mobileflow-secondary|other=ves-other,ves-other-secondary|stateChange=ves-statechange,ves-statechange-secondary|thresholdCrossingAlert=ves-thresholdCrossingAlert,ves-thresholdCrossingAlert-secondary|voiceQuality=ves-voicequality,ves-voicequality-secondary|sipSignaling=ves-sipsignaling,ves-sipsignaling-secondary collector.dmaapfile=./etc/DmaapConfig.json -header.authflag=1 +auth.method=noAuth header.authlist=sample1,$2a$10$pgjaxDzSuc6XVFEeqvxQ5u90DKJnM/u7TJTcinAlFJVaavXMWf/Zi|userid1,$2a$10$61gNubgJJl9lh3nvQvY9X.x4e5ETWJJ7ao7ZhJEvmfJigov26Z6uq|userid2,$2a$10$G52y/3uhuhWAMy.bx9Se8uzWinmbJa.dlm1LW6bYPdPkkywLDPLiy event.transform.flag=1 collector.inputQueue.maxPending = 8096 diff --git a/src/test/resources/testcollector.properties b/src/test/resources/testcollector.properties index a99fd067..c3fcca62 100644 --- a/src/test/resources/testcollector.properties +++ b/src/test/resources/testcollector.properties @@ -6,7 +6,7 @@ collector.schema.checkflag=1 collector.schema.file={\"v1\":\"./etc/CommonEventFormat_27.2.json\",\"v2\":\"./etc/CommonEventFormat_27.2.json\",\"v3\":\"./etc/CommonEventFormat_27.2.json\",\"v4\":\"./etc/CommonEventFormat_27.2.json\",\"v5\":\"./etc/CommonEventFormat_28.4.json\"} collector.dmaap.streamid=fault=sec_fault|syslog=sec_syslog|heartbeat=sec_heartbeat|measurementsForVfScaling=sec_measurement|mobileFlow=sec_mobileflow|other=sec_other|stateChange=sec_statechange|thresholdCrossingAlert=sec_thresholdCrossingAlert|voiceQuality=ves_voicequality|sipSignaling=ves_sipsignaling collector.dmaapfile=./etc/DmaapConfig.json -header.authflag=1 +auth.method=noAuth header.authlist=sample1,$2a$10$pgjaxDzSuc6XVFEeqvxQ5u90DKJnM/u7TJTcinAlFJVaavXMWf/Zi|userid1,$2a$10$61gNubgJJl9lh3nvQvY9X.x4e5ETWJJ7ao7ZhJEvmfJigov26Z6uq|userid2,$2a$10$G52y/3uhuhWAMy.bx9Se8uzWinmbJa.dlm1LW6bYPdPkkywLDPLiy event.transform.flag=1 diff --git a/version.properties b/version.properties index 6494452f..44b6acf6 100644 --- a/version.properties +++ b/version.properties @@ -1,6 +1,6 @@ major=1 minor=4 -patch=2 +patch=3 base_version=${major}.${minor}.${patch} release_version=${base_version} snapshot_version=${base_version}-SNAPSHOT -- cgit 1.2.3-korg