Make aai-resources agnostic of the embedded server (remove jetty-specific code) 53/139853/9 oslo
authorFiete Ostkamp <Fiete.Ostkamp@telekom.de>
Mon, 6 Jan 2025 10:38:34 +0000 (11:38 +0100)
committerFiete Ostkamp <fiete.ostkamp@telekom.de>
Mon, 13 Jan 2025 20:41:40 +0000 (20:41 +0000)
- small adjustments to authentication
- make users configurable via aai.basic-auth.users[] in application.properties
- remove Keycloak integration [0]

[0] for the following reasons:
- integration test (MultiTenancyTest) already not working
- dependency is ancient (uses 11, 26 is available as of writing)
- keycloak autoconfiguration is in conflict with spring security
- keycloak-specific starters have been deprecated and users are advised to
  use the out-of-the-box spring OIDC integration [1]
- there is no (and likely never will be a) starter that is compatible with spring-boot 3

[1] https://www.keycloak.org/2023/03/adapter-deprecation-update

Issue-ID: AAI-4100
Change-Id: I8440f44106f9ba2cbd4addfa88efb63329365977
Signed-off-by: Fiete Ostkamp <Fiete.Ostkamp@telekom.de>
32 files changed:
.gitignore
aai-resources/.gitignore
aai-resources/pom.xml
aai-resources/src/main/java/org/onap/aai/IncreaseNodesTool.java
aai-resources/src/main/java/org/onap/aai/ResourcesApp.java
aai-resources/src/main/java/org/onap/aai/config/AuthProperties.java [moved from aai-resources/src/main/java/org/onap/aai/config/JettyPasswordDecoder.java with 63% similarity]
aai-resources/src/main/java/org/onap/aai/config/PasswordDecoder.java [deleted file]
aai-resources/src/main/java/org/onap/aai/config/PropertyPasswordConfiguration.java [deleted file]
aai-resources/src/main/java/org/onap/aai/interceptors/pre/AuthInterceptor.java [new file with mode: 0644]
aai-resources/src/main/java/org/onap/aai/interceptors/pre/NamespaceInterceptor.java
aai-resources/src/main/java/org/onap/aai/interceptors/pre/OneWaySslAuthorization.java [deleted file]
aai-resources/src/main/java/org/onap/aai/rest/ResourcesController.java
aai-resources/src/main/java/org/onap/aai/rest/security/WebSecurityConfig.java [deleted file]
aai-resources/src/main/java/org/onap/aai/service/AuthorizationService.java
aai-resources/src/main/resources/application-keycloak.properties [deleted file]
aai-resources/src/main/resources/application.properties
aai-resources/src/main/resources/etc/appprops/aaiconfig.properties
aai-resources/src/test/java/org/onap/aai/ResourcesTestConfiguration.java
aai-resources/src/test/java/org/onap/aai/config/WebClientConfiguration.java
aai-resources/src/test/java/org/onap/aai/it/multitenancy/KeycloakTestConfiguration.java [deleted file]
aai-resources/src/test/java/org/onap/aai/it/multitenancy/KeycloakTestProperties.java [deleted file]
aai-resources/src/test/java/org/onap/aai/it/multitenancy/MultiTenancyIT.java [deleted file]
aai-resources/src/test/java/org/onap/aai/it/multitenancy/RoleHandler.java [deleted file]
aai-resources/src/test/java/org/onap/aai/rest/AbstractSpringRestTest.java
aai-resources/src/test/java/org/onap/aai/rest/AuthenticationTest.java [new file with mode: 0644]
aai-resources/src/test/java/org/onap/aai/rest/ConfigurationTest.java
aai-resources/src/test/java/org/onap/aai/rest/resources/ResourcesControllerTest.java
aai-resources/src/test/resources/application-test.properties
aai-resources/src/test/resources/it/application-keycloak-test.properties [deleted file]
aai-resources/src/test/resources/it/multi-tenancy-realm.json [deleted file]
pom.xml
version.properties

index e18083c..ab1b64a 100644 (file)
@@ -2,8 +2,6 @@
 .project
 target/
 **/logs/
-bundleconfig-local/etc/auth/aai-client-cert.p12
-bundleconfig-local/etc/auth/tomcat_keystore
 bundleconfig-local/etc/logback.xml
 /.pydevproject
 /bin/
@@ -14,4 +12,4 @@ test_csvWriter.csv
 *.iml
 aai-resources/debug-logs/EELF/
 .vscode
-.classpath
\ No newline at end of file
+.classpath
index 47d0f72..9d97990 100644 (file)
@@ -1,8 +1,6 @@
 .settings
 target/
 **/logs/
-bundleconfig-local/etc/auth/aai-client-cert.p12
-bundleconfig-local/etc/auth/tomcat_keystore
 bundleconfig-local/etc/oxm
 src/main/aai_schema
 bundleconfig-local/etc/logback.xml
@@ -15,4 +13,4 @@ bundleconfig-local/etc/logback.xml
 **/dbedgerules/**
 **/oxm/**
 **/.classpath
-.classpath
\ No newline at end of file
+.classpath
index d5dacd4..8910d5a 100644 (file)
 
 -->
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.onap.aai.resources</groupId>
     <artifactId>aai-resources</artifactId>
     <parent>
         <groupId>org.onap.aai.resources</groupId>
         <artifactId>resources</artifactId>
-        <version>1.15.4-SNAPSHOT</version>
+        <version>1.15.5-SNAPSHOT</version>
     </parent>
     <properties>
         <java.version>11</java.version>
@@ -81,9 +81,7 @@
         <gremlin.version>3.5.8</gremlin.version> -->
 
         <javax.servlet.version>4.0.1</javax.servlet.version>
-        <keycloak.version>11.0.2</keycloak.version>
-        <testcontainers.version>1.20.4</testcontainers.version>
-        <testcontainers-keycloak.version>1.6.1</testcontainers-keycloak.version>
+        <testcontainers.version>1.19.8</testcontainers.version>
         <mockito.core.version>4.4.0</mockito.core.version>
         <eclipse.persistence.version>2.7.7</eclipse.persistence.version>
         <!-- Setting some default value to not complain by editor but it will be overridden by gmaven plugin -->
             <build>
                 <plugins>
                     <plugin>
-                    <groupId>org.codehaus.groovy.maven</groupId>
-                    <artifactId>gmaven-plugin</artifactId>
-                    <version>1.0</version>
-                    <executions>
-                        <execution>
-                            <phase>pre-clean</phase>
-                        </execution>
-                    </executions>
-                </plugin>
+                        <groupId>org.codehaus.groovy.maven</groupId>
+                        <artifactId>gmaven-plugin</artifactId>
+                        <version>1.0</version>
+                        <executions>
+                            <execution>
+                                <phase>pre-clean</phase>
+                            </execution>
+                        </executions>
+                    </plugin>
                     <plugin>
                         <groupId>io.fabric8</groupId>
                         <artifactId>docker-maven-plugin</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-web</artifactId>
+            <artifactId>spring-boot-starter-jersey</artifactId>
             <exclusions>
                 <exclusion>
                     <groupId>org.springframework.boot</groupId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-test</artifactId>
-            <scope>test</scope>
+            <artifactId>spring-boot-starter-jetty</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-jetty</artifactId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+            <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <version>6.6</version>
         </dependency>
         <dependency>
-          <groupId>org.hamcrest</groupId>
-          <artifactId>hamcrest</artifactId>
-          <version>2.2</version>
-          <exclusions>
-            <exclusion>
-              <groupId>junit</groupId>
-              <artifactId>junit</artifactId>
-            </exclusion>
-          </exclusions>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest</artifactId>
+            <version>2.2</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>junit</groupId>
+                    <artifactId>junit</artifactId>
+                </exclusion>
+            </exclusions>
         </dependency>
         <dependency>
             <groupId>com.google.guava</groupId>
             <scope>test</scope>
         </dependency>
         <dependency>
-          <groupId>org.mockito</groupId>
-          <artifactId>mockito-junit-jupiter</artifactId>
-          <scope>test</scope>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-junit-jupiter</artifactId>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>com.beust</groupId>
         <dependency>
             <groupId>org.javatuples</groupId>
             <artifactId>javatuples</artifactId>
-            <scope>compile</scope>
+            <version>1.2</version>
         </dependency>
         <dependency>
             <groupId>com.google.code.gson</groupId>
                 </exclusion>
             </exclusions>
         </dependency>
-        <!--
-            Explicitly stating the security spring framework and
-            exclude the bouncy castle since that is somehow overwriting
-            our p12 file decryption that's built into java security
-            This will cause the password is incorrect
-            This needs to be added back if org.bouncy castle dependency
-            sneaks backs in and causing issues with the two way ssl
-        -->
-        <dependency>
-            <groupId>org.springframework.security</groupId>
-            <artifactId>spring-security-rsa</artifactId>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.bouncycastle</groupId>
-                    <artifactId>bcpkix-jdk15on</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
-            <groupId>io.netty</groupId>
-            <artifactId>netty-handler</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>io.netty</groupId>
-            <artifactId>netty-all</artifactId>
-        </dependency>
 
         <!-- Only used for the WebTestClient -->
         <dependency>
             <artifactId>gremlin-groovy</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-security</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-spring-boot-starter</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.github.dasniko</groupId>
-            <artifactId>testcontainers-keycloak</artifactId>
-            <version>${testcontainers-keycloak.version}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-          <groupId>org.junit.jupiter</groupId>
-          <artifactId>junit-jupiter</artifactId>
-          <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-admin-client</artifactId>
-            <version>${keycloak.version}</version>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
             <scope>test</scope>
         </dependency>
         <dependency>
-                       <groupId>org.projectlombok</groupId>
-                       <artifactId>lombok</artifactId>
-                       <version>1.18.34</version>
-                       <scope>provided</scope>
-               </dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.34</version>
+            <scope>provided</scope>
+        </dependency>
         <dependency>
-                       <groupId>com.fasterxml.jackson.dataformat</groupId>
-                       <artifactId>jackson-dataformat-xml</artifactId>
-               </dependency>
+            <groupId>com.fasterxml.jackson.dataformat</groupId>
+            <artifactId>jackson-dataformat-xml</artifactId>
+        </dependency>
     </dependencies>
     <dependencyManagement>
         <dependencies>
-            <dependency>
-                <groupId>org.keycloak.bom</groupId>
-                <artifactId>keycloak-adapter-bom</artifactId>
-                <version>${keycloak.version}</version>
-                <type>pom</type>
-                <scope>import</scope>
-            </dependency>
             <dependency>
                 <groupId>org.springframework.cloud</groupId>
                 <artifactId>spring-cloud-dependencies</artifactId>
             <resource>
                 <directory>${project.basedir}/src/main/resources/etc/auth/</directory>
                 <includes>
-                    <include>aai-client-cert.p12</include>
-                    <include>tomcat_keystore</include>
                     <include>aai_policy.json</include>
                 </includes>
                 <targetPath>${project.build.directory}/swm/package/nix/dist_files/opt/app/${project.artifactId}/appconfig</targetPath>
                 <artifactId>maven-deploy-plugin</artifactId>
             </plugin>
             <plugin>
-              <artifactId>maven-resources-plugin</artifactId>
-              <version>3.0.0</version>
-              <executions>
-                <execution>
-                  <id>copy-fat-jar</id>
-                  <phase>post-integration-test</phase>
-                  <goals>
-                    <goal>copy-resources</goal>
-                  </goals>
-                  <configuration>
-                      <outputDirectory>${aai.build.directory}/lib/</outputDirectory>
-                      <resources>
-                          <resource>
-                              <directory>${project.build.directory}/</directory>
-                              <includes>
-                                  <include>${project.artifactId}-${project.version}.jar</include>
-                              </includes>
-                              <filtering>false</filtering>
-                          </resource>
-                      </resources>
-                  </configuration>
-                </execution>
-              </executions>
+                <artifactId>maven-resources-plugin</artifactId>
+                <version>3.0.0</version>
+                <executions>
+                    <execution>
+                        <id>copy-fat-jar</id>
+                        <phase>post-integration-test</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${aai.build.directory}/lib/</outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>${project.build.directory}/</directory>
+                                    <includes>
+                                        <include>${project.artifactId}-${project.version}.jar</include>
+                                    </includes>
+                                    <filtering>false</filtering>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                </executions>
             </plugin>
             <plugin>
                 <groupId>org.springframework.boot</groupId>
index 9331f2f..68ed2fb 100644 (file)
@@ -41,7 +41,6 @@ import org.onap.aai.introspection.LoaderFactory;
 import org.onap.aai.introspection.ModelType;
 import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
 import org.onap.aai.logging.ErrorLogHelper;
-import org.onap.aai.restclient.PropertyPasswordConfiguration;
 import org.onap.aai.serialization.db.EdgeSerializer;
 import org.onap.aai.serialization.engines.TransactionalGraphEngine;
 import org.onap.aai.setup.SchemaVersions;
@@ -76,8 +75,6 @@ public class IncreaseNodesTool {
             throws AAIUnknownObjectException, UnsupportedEncodingException, AAIException {
 
         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
-        PropertyPasswordConfiguration initializer = new PropertyPasswordConfiguration();
-        initializer.initialize(context);
         try {
             context.scan("org.onap.aai.config", "org.onap.aai.setup");
             context.refresh();
@@ -129,7 +126,7 @@ public class IncreaseNodesTool {
      * /cloud-infrastructure/pservers/pserver/
      * /network/pnfs/pnf/
      * /cloud-infrastructure/pservers/pserver/random-056fd6c4-7313-4fa0-b854-0d9983bdb0ab/p-interfaces/p-interface/
-     * 
+     *
      * @param
      * @param
      * @param cArgs
index 51f5609..7e1bd3a 100644 (file)
@@ -30,7 +30,6 @@ import org.onap.aai.dbmap.AAIGraph;
 import org.onap.aai.exceptions.AAIException;
 import org.onap.aai.logging.ErrorLogHelper;
 import org.onap.aai.nodes.NodeIngestor;
-import org.onap.aai.restclient.PropertyPasswordConfiguration;
 import org.onap.aai.util.AAIConfig;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -42,9 +41,11 @@ import org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoCo
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
 import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.core.env.Environment;
 import org.springframework.core.env.Profiles;
 
+@EnableConfigurationProperties
 @SpringBootApplication(
         exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class,
                 HibernateJpaAutoConfiguration.class, CassandraDataAutoConfiguration.class, CassandraAutoConfiguration.class})
@@ -105,7 +106,6 @@ public class ResourcesApp {
             SpringApplication app = new SpringApplication(ResourcesApp.class);
             app.setLogStartupInfo(false);
             app.setRegisterShutdownHook(true);
-            app.addInitializers(new PropertyPasswordConfiguration());
             env = app.run(args).getEnvironment();
         } catch (Exception ex) {
             AAIException aai = null;
@@ -132,8 +132,6 @@ public class ResourcesApp {
         logger.info("Resources MicroService Started");
         logger.debug("Resources MicroService Started");
 
-        System.out.println("Resources Microservice Started");
-
     }
 
     public static void setDefaultProps() {
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * org.onap.aai
  * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package org.onap.aai.config;
 
-import org.eclipse.jetty.util.security.Password;
+import java.util.List;
 
-public class JettyPasswordDecoder implements PasswordDecoder {
+import javax.validation.constraints.NotEmpty;
 
-    @Override
-    public String decode(String input) {
-        if (input.startsWith("OBF:")) {
-            return Password.deobfuscate(input);
-        }
-        return Password.deobfuscate("OBF:" + input);
-    }
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import lombok.Data;
+
+@Data
+@Configuration
+@ConfigurationProperties(prefix = "aai.basic-auth")
+public class AuthProperties {
+
+  boolean enabled = true;
+
+  @NotEmpty
+  List<User> users;
+
+  @Data
+  public static class User {
+    private String username;
+    private String password;
+  }
 }
diff --git a/aai-resources/src/main/java/org/onap/aai/config/PasswordDecoder.java b/aai-resources/src/main/java/org/onap/aai/config/PasswordDecoder.java
deleted file mode 100644 (file)
index 8ad75d9..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.aai.config;
-
-public interface PasswordDecoder {
-
-    String decode(String input);
-}
diff --git a/aai-resources/src/main/java/org/onap/aai/config/PropertyPasswordConfiguration.java b/aai-resources/src/main/java/org/onap/aai/config/PropertyPasswordConfiguration.java
deleted file mode 100644 (file)
index f205804..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.aai.config;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.Charset;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Properties;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.io.IOUtils;
-import org.springframework.context.ApplicationContextInitializer;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.core.env.ConfigurableEnvironment;
-import org.springframework.core.env.EnumerablePropertySource;
-import org.springframework.core.env.MapPropertySource;
-import org.springframework.core.env.PropertySource;
-
-import lombok.extern.slf4j.Slf4j;
-
-@Slf4j
-public class PropertyPasswordConfiguration implements ApplicationContextInitializer<ConfigurableApplicationContext> {
-
-    private static final Pattern decodePasswordPattern = Pattern.compile("password\\((.*?)\\)");
-    private PasswordDecoder passwordDecoder = new JettyPasswordDecoder();
-
-    @Override
-    public void initialize(ConfigurableApplicationContext applicationContext) {
-        ConfigurableEnvironment environment = applicationContext.getEnvironment();
-        String certPath = environment.getProperty("server.certs.location");
-        File passwordFile = null;
-        File passphrasesFile = null;
-        InputStream passwordStream = null;
-        InputStream passphrasesStream = null;
-        Map<String, Object> sslProps = new LinkedHashMap<>();
-
-        // Override the passwords from application.properties if we find AAF certman files
-        if (certPath != null) {
-            try {
-                passwordFile = new File(certPath + ".password");
-                passwordStream = new FileInputStream(passwordFile);
-
-                if (passwordStream != null) {
-                    String keystorePassword = null;
-
-                    keystorePassword = IOUtils.toString(passwordStream, Charset.defaultCharset());
-                    if (keystorePassword != null) {
-                        keystorePassword = keystorePassword.trim();
-                    }
-                    sslProps.put("server.ssl.key-store-password", keystorePassword);
-                    sslProps.put("schema.service.ssl.key-store-password", keystorePassword);
-                } else {
-                    log.info("Not using AAF Certman password file");
-                }
-            } catch (IOException e) {
-                log.warn("Not using AAF Certman password file, e=" + e.getMessage());
-            } finally {
-                if (passwordStream != null) {
-                    try {
-                        passwordStream.close();
-                    } catch (Exception e) {
-                    }
-                }
-            }
-            try {
-                passphrasesFile = new File(certPath + ".passphrases");
-                passphrasesStream = new FileInputStream(passphrasesFile);
-
-                if (passphrasesStream != null) {
-                    String truststorePassword = null;
-                    Properties passphrasesProps = new Properties();
-                    passphrasesProps.load(passphrasesStream);
-                    truststorePassword = passphrasesProps.getProperty("cadi_truststore_password");
-                    if (truststorePassword != null) {
-                        truststorePassword = truststorePassword.trim();
-                    }
-                    sslProps.put("server.ssl.trust-store-password", truststorePassword);
-                    sslProps.put("schema.service.ssl.trust-store-password", truststorePassword);
-                } else {
-                    log.info("Not using AAF Certman passphrases file");
-                }
-            } catch (IOException e) {
-                log.warn("Not using AAF Certman passphrases file, e=" + e.getMessage());
-            } finally {
-                if (passphrasesStream != null) {
-                    try {
-                        passphrasesStream.close();
-                    } catch (Exception e) {
-                    }
-                }
-            }
-        }
-        for (PropertySource<?> propertySource : environment.getPropertySources()) {
-            Map<String, Object> propertyOverrides = new LinkedHashMap<>();
-            decodePasswords(propertySource, propertyOverrides);
-            if (!propertyOverrides.isEmpty()) {
-                PropertySource<?> decodedProperties =
-                        new MapPropertySource("decoded " + propertySource.getName(), propertyOverrides);
-                environment.getPropertySources().addBefore(propertySource.getName(), decodedProperties);
-            }
-
-        }
-        if (!sslProps.isEmpty()) {
-            log.info("Using AAF Certman files");
-            PropertySource<?> additionalProperties = new MapPropertySource("additionalProperties", sslProps);
-            environment.getPropertySources().addFirst(additionalProperties);
-        }
-    }
-
-    private void decodePasswords(PropertySource<?> source, Map<String, Object> propertyOverrides) {
-        if (source instanceof EnumerablePropertySource) {
-            EnumerablePropertySource<?> enumerablePropertySource = (EnumerablePropertySource<?>) source;
-            for (String key : enumerablePropertySource.getPropertyNames()) {
-                Object rawValue = source.getProperty(key);
-                if (rawValue instanceof String) {
-                    String decodedValue = decodePasswordsInString((String) rawValue);
-                    propertyOverrides.put(key, decodedValue);
-                }
-            }
-        }
-    }
-
-    private String decodePasswordsInString(String input) {
-        if (input == null)
-            return null;
-        StringBuffer output = new StringBuffer();
-        Matcher matcher = decodePasswordPattern.matcher(input);
-        while (matcher.find()) {
-            String replacement = passwordDecoder.decode(matcher.group(1));
-            matcher.appendReplacement(output, replacement);
-        }
-        matcher.appendTail(output);
-        return output.toString();
-    }
-
-}
diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/AuthInterceptor.java b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/AuthInterceptor.java
new file mode 100644 (file)
index 0000000..e590d9f
--- /dev/null
@@ -0,0 +1,87 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.
+ * ================================================================================
+ * 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.aai.interceptors.pre;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.regex.Pattern;
+
+import javax.annotation.Priority;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.PreMatching;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.onap.aai.ResourcesProfiles;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.interceptors.AAIContainerFilter;
+import org.onap.aai.logging.ErrorLogHelper;
+import org.onap.aai.service.AuthorizationService;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Component;
+
+import lombok.RequiredArgsConstructor;
+
+@Component
+@PreMatching
+@RequiredArgsConstructor
+@Profile(ResourcesProfiles.ONE_WAY_SSL) // this mainly serves the purpose of making the tests work
+@Priority(AAIRequestFilterPriority.AUTHORIZATION)
+public class AuthInterceptor extends AAIContainerFilter implements ContainerRequestFilter {
+
+  private static final Pattern PATTERN_ECHO = Pattern.compile("^.*/util/echo$");
+  private static final Pattern PATTERN_ACTUATOR = Pattern.compile("^.*/actuator/.*$");
+  private static final AAIException AAI_EXCEPTION = new AAIException("AAI_3300");
+  private final AuthorizationService authorizationService;
+
+  @Override
+  public void filter(ContainerRequestContext requestContext) throws IOException {
+    String path = requestContext.getUriInfo().getRequestUri().getPath();
+    if (PATTERN_ECHO.matcher(path).matches() || PATTERN_ACTUATOR.matcher(path).matches()) {
+      return;
+    }
+
+    String basicAuth = requestContext.getHeaders().getFirst("Authorization");
+    if (basicAuth == null || !basicAuth.startsWith("Basic ")) {
+      Response errorResponse = errorResponse("AAI_3300", requestContext.getAcceptableMediaTypes());
+      requestContext.abortWith(errorResponse);
+      return;
+    }
+
+    if (!authorizationService.isAuthorized(basicAuth)) {
+      Response errorResponse = errorResponse("AAI_3300", requestContext.getAcceptableMediaTypes());
+      requestContext.abortWith(errorResponse);
+      return;
+    }
+  }
+
+  private Response errorResponse(String errorCode, List<MediaType> acceptHeaderValues) {
+
+    return Response
+      .status(AAI_EXCEPTION.getErrorObject().getHTTPResponseCode())
+      .entity(ErrorLogHelper.getRESTAPIErrorResponse(acceptHeaderValues, AAI_EXCEPTION, new ArrayList<>()))
+      .build();
+  }
+
+}
index c97e475..7889a2c 100644 (file)
@@ -41,7 +41,6 @@ import javax.xml.transform.Source;
 import javax.xml.transform.stream.StreamResult;
 import javax.xml.transform.stream.StreamSource;
 
-import org.onap.aai.IncreaseNodesTool;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -67,7 +66,7 @@ import org.xml.sax.InputSource;
 @ConditionalOnProperty(value = "aai.remove-xmlns.enabled", havingValue = "true", matchIfMissing = true)
 public class NamespaceInterceptor implements ReaderInterceptor {
 
-    private static final Logger log = LoggerFactory.getLogger(IncreaseNodesTool.class);
+    private static final Logger log = LoggerFactory.getLogger(NamespaceInterceptor.class);
     private static final String xslStr = String.join("\n",
         "<xsl:transform xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">",
         "<xsl:output version=\"1.0\" encoding=\"UTF-8\" indent=\"no\"/>",
diff --git a/aai-resources/src/main/java/org/onap/aai/interceptors/pre/OneWaySslAuthorization.java b/aai-resources/src/main/java/org/onap/aai/interceptors/pre/OneWaySslAuthorization.java
deleted file mode 100644 (file)
index b532105..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.aai.interceptors.pre;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-import javax.annotation.Priority;
-import javax.ws.rs.container.ContainerRequestContext;
-import javax.ws.rs.container.ContainerRequestFilter;
-import javax.ws.rs.container.PreMatching;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.onap.aai.ResourcesProfiles;
-import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.interceptors.AAIContainerFilter;
-import org.onap.aai.logging.ErrorLogHelper;
-import org.onap.aai.service.AuthorizationService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Profile;
-
-@Profile(ResourcesProfiles.ONE_WAY_SSL)
-@PreMatching
-@Priority(AAIRequestFilterPriority.AUTHORIZATION)
-public class OneWaySslAuthorization extends AAIContainerFilter implements ContainerRequestFilter {
-
-    @Autowired
-    private AuthorizationService authorizationService;
-
-    @Override
-    public void filter(ContainerRequestContext containerRequestContext) throws IOException {
-
-        if (containerRequestContext.getUriInfo().getRequestUri().getPath().matches("^.*/util/echo$")) {
-            return;
-        }
-
-        String basicAuth = containerRequestContext.getHeaderString("Authorization");
-        List<MediaType> acceptHeaderValues = containerRequestContext.getAcceptableMediaTypes();
-
-        if (basicAuth == null || !basicAuth.startsWith("Basic ")) {
-            Optional<Response> responseOptional = errorResponse("AAI_3300", acceptHeaderValues);
-            containerRequestContext.abortWith(responseOptional.get());
-            return;
-        }
-
-        basicAuth = basicAuth.replaceAll("Basic ", "");
-
-        if (!authorizationService.checkIfUserAuthorized(basicAuth)) {
-            Optional<Response> responseOptional = errorResponse("AAI_3300", acceptHeaderValues);
-            containerRequestContext.abortWith(responseOptional.get());
-            return;
-        }
-
-    }
-
-    private Optional<Response> errorResponse(String errorCode, List<MediaType> acceptHeaderValues) {
-        AAIException aaie = new AAIException(errorCode);
-        return Optional.of(Response.status(aaie.getErrorObject().getHTTPResponseCode())
-                .entity(ErrorLogHelper.getRESTAPIErrorResponse(acceptHeaderValues, aaie, new ArrayList<>())).build());
-
-    }
-}
index 12839d4..1f66697 100644 (file)
@@ -34,8 +34,6 @@ import javax.ws.rs.core.*;
 import javax.ws.rs.core.Response.Status;
 
 import org.apache.commons.lang3.ObjectUtils;
-import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount;
-import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
 import org.onap.aai.concurrent.AaiCallable;
 import org.onap.aai.introspection.Introspector;
 import org.onap.aai.introspection.sideeffect.OwnerCheck;
@@ -65,7 +63,7 @@ public class ResourcesController extends RESTAPI {
             @Context HttpHeaders headers,
             @Context UriInfo info,
             @Context HttpServletRequest req) {
-        Set<String> roles = getRoles(req.getUserPrincipal(), req.getMethod());
+        Set<String> roles = Collections.emptySet();
         MediaType mediaType = headers.getMediaType();
         return resourcesService.handleWrites(mediaType, HttpMethod.PUT, content, versionParam, uri, headers, info, roles);
     }
@@ -96,7 +94,7 @@ public class ResourcesController extends RESTAPI {
             @Context HttpHeaders headers,
             @Context UriInfo info,
             @Context HttpServletRequest req) {
-        Set<String> roles = getRoles(req.getUserPrincipal(), req.getMethod());
+        Set<String> roles = Collections.emptySet();
         MediaType mediaType = MediaType.APPLICATION_JSON_TYPE;
         return resourcesService.handleWrites(mediaType, HttpMethod.MERGE_PATCH, content, versionParam, uri, headers, info, roles);
 
@@ -134,7 +132,7 @@ public class ResourcesController extends RESTAPI {
             @Context HttpHeaders headers,
             @Context UriInfo info,
             @Context HttpServletRequest req) {
-        Set<String> roles = getRoles(req.getUserPrincipal(), req.getMethod());
+        Set<String> roles = Collections.emptySet();
         Pageable pageable = includeTotalCount == false
             ? new Pageable(resultIndex -1, resultSize)
             : new Pageable(resultIndex -1, resultSize).includeTotalCount();
@@ -159,7 +157,7 @@ public class ResourcesController extends RESTAPI {
             @Context UriInfo info,
             @QueryParam("resource-version") String resourceVersion,
             @Context HttpServletRequest req) {
-        Set<String> roles = getRoles(req.getUserPrincipal(), req.getMethod());
+        Set<String> roles = Collections.emptySet();
         return resourcesService.delete(versionParam, uri, headers, info, req, roles);
     }
 
@@ -210,29 +208,4 @@ public class ResourcesController extends RESTAPI {
     protected boolean isEmptyObject(Introspector obj) {
         return "{}".equals(obj.marshal(false));
     }
-
-    private Set<String> getRoles(Principal userPrincipal, String method) {
-        KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) userPrincipal;
-        if (ObjectUtils.isEmpty(token)) {
-            return Collections.emptySet();
-        }
-        SimpleKeycloakAccount account = (SimpleKeycloakAccount) token.getDetails();
-        if (ObjectUtils.isEmpty(account)) {
-            return Collections.emptySet();
-        }
-        // When the request is not a GET, we need to exclude ReadOnly access roles
-        if (isNotGetRequest(method)) {
-            return getExcludedReadOnlyAccessRoles(account);
-        }
-        return account.getRoles();
-    }
-
-    private Set<String> getExcludedReadOnlyAccessRoles(SimpleKeycloakAccount account) {
-        return account.getRoles().stream().filter(role -> !role.endsWith(OwnerCheck.READ_ONLY_SUFFIX))
-                .collect(Collectors.toSet());
-    }
-
-    private boolean isNotGetRequest(String method) {
-        return !Action.GET.name().equalsIgnoreCase(method);
-    }
 }
diff --git a/aai-resources/src/main/java/org/onap/aai/rest/security/WebSecurityConfig.java b/aai-resources/src/main/java/org/onap/aai/rest/security/WebSecurityConfig.java
deleted file mode 100644 (file)
index c63a70a..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright (C) 2019 Nordix Foundation.
- * Modifications Copyright (C) 2019 AT&T Intellectual Property.
- * Modifications Copyright (C) 2020 Bell Canada.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.rest.security;
-
-import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
-import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
-import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
-import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Import;
-import org.springframework.context.annotation.Profile;
-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.builders.WebSecurity;
-import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
-import org.springframework.security.core.session.SessionRegistryImpl;
-import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
-import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
-import org.springframework.security.web.session.HttpSessionEventPublisher;
-
-@Profile("keycloak")
-@KeycloakConfiguration
-@Import({KeycloakSpringBootConfigResolver.class})
-public class WebSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
-
-    @Autowired
-    public void configureGlobal(AuthenticationManagerBuilder auth) {
-        KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
-        keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
-        auth.authenticationProvider(keycloakAuthenticationProvider);
-    }
-
-    @Bean
-    public ServletListenerRegistrationBean<HttpSessionEventPublisher> httpSessionEventPublisher() {
-        return new ServletListenerRegistrationBean<>(new HttpSessionEventPublisher());
-    }
-
-    @Bean
-    @Override
-    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
-        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
-    }
-
-    @Override
-    protected void configure(HttpSecurity http) throws Exception {
-        super.configure(http);
-        http.authorizeRequests().antMatchers("/**").permitAll().and().csrf().disable();
-    }
-
-    @Override
-    public void configure(WebSecurity web) {
-        web.ignoring().regexMatchers("^.*/util/echo$");
-    }
-
-}
index 0c219a7..7b420b9 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * org.onap.aai
  * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package org.onap.aai.service;
 
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.nio.file.Files;
-import java.nio.file.Path;
 import java.util.Base64;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.stream.Stream;
+import java.util.Set;
+import java.util.stream.Collectors;
 
-import javax.annotation.PostConstruct;
-
-import org.eclipse.jetty.util.security.Password;
-import org.onap.aai.ResourcesProfiles;
-import org.onap.aai.util.AAIConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.annotation.Profile;
+import org.onap.aai.config.AuthProperties;
 import org.springframework.stereotype.Service;
 
-@Profile(ResourcesProfiles.ONE_WAY_SSL)
+/**
+ * Should be removed once Spring Security-based auth works
+ */
 @Service
 public class AuthorizationService {
 
-    private static final Logger logger = LoggerFactory.getLogger(AuthorizationService.class);
-
-    private final Map<String, String> authorizedUsers = new HashMap<>();
-
-    private static final Base64.Encoder ENCODER = Base64.getEncoder();
-
-    @PostConstruct
-    public void init() {
-
-        String basicAuthFile = getBasicAuthFilePath();
-
-        try (Stream<String> stream = Files.lines(Path.of(basicAuthFile))) {
-            stream.filter(line -> !line.startsWith("#")).forEach(str -> {
-                byte[] bytes = null;
-
-                String usernamePassword = null;
-                String accessType = null;
-
-                try {
-                    String[] userAccessType = str.split(",");
-
-                    if (userAccessType == null || userAccessType.length != 2) {
-                        throw new RuntimeException(
-                                "Please check the realm.properties file as it is not conforming to the basic auth");
-                    }
-
-                    usernamePassword = userAccessType[0];
-                    accessType = userAccessType[1];
-
-                    String[] usernamePasswordArray = usernamePassword.split(":");
-
-                    if (usernamePasswordArray == null || usernamePasswordArray.length != 3) {
-                        throw new RuntimeException("This username / pwd is not a valid entry in realm.properties");
-                    }
-
-                    String username = usernamePasswordArray[0];
-                    String password = null;
-
-                    if (str.contains("OBF:")) {
-                        password = usernamePasswordArray[1] + ":" + usernamePasswordArray[2];
-                        password = Password.deobfuscate(password);
-                    }
-
-                    bytes = ENCODER.encode((username + ":" + password).getBytes("UTF-8"));
-
-                    authorizedUsers.put(new String(bytes), accessType);
-
-                } catch (UnsupportedEncodingException e) {
-                    logger.error("Unable to support the encoding of the file" + basicAuthFile);
-                }
-
-                authorizedUsers.put(new String(ENCODER.encode(bytes)), accessType);
-            });
-        } catch (IOException e) {
-            logger.error("IO Exception occurred during the reading of realm.properties", e);
-        }
-    }
+  // Saved in this format for best performance
+  private final Set<String> authorizedHeaders;
+
+  public AuthorizationService(AuthProperties authProperties) {
+    authorizedHeaders = getAuthorizedHeaders(authProperties);
+  }
+
+  public boolean isAuthorized(String authHeaderValue) {
+    return authorizedHeaders.contains(authHeaderValue);
+  }
+
+  /**
+   * Returns valid Bearer auth headers for all users.
+   * @param authProperties
+   * @param encoder
+   * @return
+   */
+  private Set<String> getAuthorizedHeaders(AuthProperties authProperties) {
+    Base64.Encoder encoder = Base64.getEncoder();
+    return authProperties.getUsers().stream()
+      .map(user -> user.getUsername() + ":" + user.getPassword())
+      .map(usernamePasswordPair -> encoder.encode(usernamePasswordPair.getBytes()))
+      .map(String::new)
+      .map(encodedPair -> "Basic " + encodedPair)
+      .collect(Collectors.toSet());
+  }
 
-    public boolean checkIfUserAuthorized(String authorization) {
-        return authorizedUsers.containsKey(authorization) && "admin".equals(authorizedUsers.get(authorization));
-    }
 
-    public String getBasicAuthFilePath() {
-        return AAIConstants.AAI_HOME_ETC_AUTH + AAIConstants.AAI_FILESEP + "realm.properties";
-    }
 }
diff --git a/aai-resources/src/main/resources/application-keycloak.properties b/aai-resources/src/main/resources/application-keycloak.properties
deleted file mode 100644 (file)
index d398256..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-
-spring.autoconfigure.exclude=\
-  org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
-  org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
-
-multi.tenancy.enabled=true
-keycloak.auth-server-url=http://localhost:8180/auth
-keycloak.realm=aai-resources
-keycloak.resource=aai-resources-app
-keycloak.public-client=true
-keycloak.principal-attribute=preferred_username
-
-keycloak.ssl-required=external
-keycloak.bearer-only=true
\ No newline at end of file
index f0ef368..c0c805f 100644 (file)
@@ -20,7 +20,6 @@ server.servlet.context-path=/
 spring.autoconfigure.exclude=\
   org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
   org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
-  org.keycloak.adapters.springboot.KeycloakAutoConfiguration,\
   org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
   org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration
 
@@ -37,21 +36,8 @@ server.tomcat.max-idle-time=60000
 # If you get an application startup failure that the port is already taken
 # If thats not it, please check if the key-store file path makes sense
 server.local.startpath=src/main/resources
-server.basic.auth.location=${server.local.startpath}/etc/auth/realm.properties
-server.certs.location=${server.local.startpath}/etc/auth/
-#server.keystore.name=keystore.jks
-server.keystore.name=aai_keystore
-server.truststore.name=aai_keystore
-server.port=8447
 
-server.ssl.enabled=false
-server.ssl.enabled-protocols=TLSv1.1,TLSv1.2
-server.ssl.key-store=${server.certs.location}${server.keystore.name}
-server.ssl.key-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
-server.ssl.trust-store=${server.certs.location}${server.truststore.name}
-server.ssl.trust-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
-server.ssl.client-auth=want
-server.ssl.key-store-type=JKS
+server.port=8447
 
 null.db.serialization.enabled=true
 
@@ -103,10 +89,6 @@ schema.service.nodes.endpoint=nodes?version=
 schema.service.edges.endpoint=edgerules?version=
 schema.service.versions.endpoint=versions
 
-schema.service.ssl.key-store=${server.certs.location}${server.keystore.name}
-schema.service.ssl.trust-store=${server.certs.location}${server.truststore.name}
-schema.service.ssl.key-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
-schema.service.ssl.trust-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
 schema.service.versions.override=false
 
 #To Expose the Prometheus scraping endpoint
@@ -134,14 +116,6 @@ delta.events.enabled=false
 validation.service.client=one-way-ssl
 # Base url for the validation service
 validation.service.base.url=https://localhost:9501/services/validation-service
-# Client certificate to use to make the request to validation
-validation.service.ssl.key-store=${server.local.startpath}/etc/auth/aai-client-cert.p12
-# Truststore to use to make the request to validation
-validation.service.ssl.trust-store=${server.local.startpath}/etc/auth/tomcat_keystore
-# Client certificate password for the validation
-validation.service.ssl.key-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
-# Truststore password for the validation
-validation.service.ssl.trust-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
 # Amount of time that the client should wait in milliseconds before request failing
 validation.service.timeout-in-milliseconds=3000
 # List of aai node types that should be send to the validation microservice
@@ -163,3 +137,7 @@ aai.actuator.echo.enabled=false
 
 aai.notifications.enabled=false
 aai.graph.properties.path=${server.local.startpath}/etc/appprops/janusgraph-realtime.properties
+
+aai.basic-auth.enabled=true
+aai.basic-auth.users[0].username=AAI
+aai.basic-auth.users[0].password=AAI
index ecbbcb1..cd19734 100644 (file)
@@ -48,11 +48,6 @@ aai.server.url.base=https://localhost:8443/aai/
 aai.server.url=https://localhost:8443/aai/v20/
 aai.global.callback.url=https://localhost:8443/aai/
 
-aai.truststore.filename=aai_keystore
-aai.truststore.passwd.x=OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0
-aai.keystore.filename=aai-client-cert.p12
-aai.keystore.passwd.x=
-
 aai.notification.current.version=v20
 aai.notificationEvent.default.status=UNPROCESSED
 aai.notificationEvent.default.eventType=AAI-EVENT
index 93b1519..0d7ff7e 100644 (file)
@@ -24,7 +24,6 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.security.KeyStore;
 
 import javax.net.ssl.SSLContext;
 
@@ -63,20 +62,7 @@ public class ResourcesTestConfiguration {
 
         RestTemplate restTemplate = null;
         if (env.acceptsProfiles(Profiles.of(ResourcesProfiles.TWO_WAY_SSL, ResourcesProfiles.ONE_WAY_SSL))) {
-            char[] trustStorePassword = env.getProperty("server.ssl.trust-store-password").toCharArray();
-            char[] keyStorePassword = env.getProperty("server.ssl.key-store-password").toCharArray();
-
-            String keyStore = env.getProperty("server.ssl.key-store");
-            String trustStore = env.getProperty("server.ssl.trust-store");
-            SSLContextBuilder sslContextBuilder = SSLContextBuilder.create();
-
-            if (env.acceptsProfiles(Profiles.of(ResourcesProfiles.TWO_WAY_SSL))) {
-                sslContextBuilder =
-                        sslContextBuilder.loadKeyMaterial(loadPfx(keyStore, keyStorePassword), keyStorePassword);
-            }
-
-            SSLContext sslContext =
-                    sslContextBuilder.loadTrustMaterial(ResourceUtils.getFile(trustStore), trustStorePassword).build();
+            SSLContext sslContext = SSLContextBuilder.create().build();
 
             HttpClient client = HttpClients.custom().setSSLContext(sslContext)
                     .setSSLHostnameVerifier((s, sslSession) -> true).build();
@@ -113,13 +99,4 @@ public class ResourcesTestConfiguration {
 
         return restTemplate;
     }
-
-    private KeyStore loadPfx(String file, char[] password) throws Exception {
-        KeyStore keyStore = KeyStore.getInstance("PKCS12");
-        File key = ResourceUtils.getFile(file);
-        try (InputStream in = new FileInputStream(key)) {
-            keyStore.load(in, password);
-        }
-        return keyStore;
-    }
 }
index e412ded..e317ef0 100644 (file)
@@ -1,3 +1,23 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.
+ * ================================================================================
+ * 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.aai.config;
 
 import java.time.Duration;
@@ -7,7 +27,7 @@ import org.onap.aai.setup.SchemaVersions;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.test.context.TestConfiguration;
-import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.boot.test.web.server.LocalServerPort;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.context.annotation.Primary;
diff --git a/aai-resources/src/test/java/org/onap/aai/it/multitenancy/KeycloakTestConfiguration.java b/aai-resources/src/test/java/org/onap/aai/it/multitenancy/KeycloakTestConfiguration.java
deleted file mode 100644 (file)
index 1e47c42..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.aai.it.multitenancy;
-
-import com.github.dockerjava.api.model.ExposedPort;
-import com.github.dockerjava.api.model.HostConfig;
-import com.github.dockerjava.api.model.PortBinding;
-import com.github.dockerjava.api.model.Ports;
-
-import dasniko.testcontainers.keycloak.KeycloakContainer;
-
-import org.keycloak.adapters.springboot.KeycloakSpringBootProperties;
-import org.keycloak.admin.client.Keycloak;
-import org.keycloak.admin.client.KeycloakBuilder;
-import org.keycloak.representations.adapters.config.AdapterConfig;
-import org.springframework.boot.test.context.TestConfiguration;
-import org.springframework.context.annotation.Bean;
-
-@TestConfiguration
-class KeycloakTestConfiguration {
-
-    @Bean
-    public AdapterConfig adapterConfig() {
-        return new KeycloakSpringBootProperties();
-    }
-
-    @Bean
-    KeycloakContainer keycloakContainer(KeycloakTestProperties properties) {
-        KeycloakContainer keycloak =
-                new KeycloakContainer("jboss/keycloak:12.0.4").withRealmImportFile(properties.realmJson)
-                        .withCreateContainerCmdModifier(cmd -> cmd.withHostConfig(new HostConfig().withPortBindings(
-                                new PortBinding(Ports.Binding.bindPort(Integer.parseInt(properties.port)),
-                                        new ExposedPort(8080)))));
-        keycloak.start();
-        return keycloak;
-    }
-
-    @Bean
-    Keycloak keycloakAdminClient(KeycloakContainer keycloak, KeycloakTestProperties properties) {
-        return KeycloakBuilder.builder().serverUrl(keycloak.getAuthServerUrl()).realm(properties.realm)
-                .clientId(properties.adminCli).username(keycloak.getAdminUsername())
-                .password(keycloak.getAdminPassword()).build();
-    }
-
-    @Bean
-    RoleHandler roleHandler(Keycloak adminClient, KeycloakTestProperties properties) {
-        return new RoleHandler(adminClient, properties);
-    }
-
-    @Bean
-    KeycloakTestProperties properties() {
-        return new KeycloakTestProperties();
-    }
-}
diff --git a/aai-resources/src/test/java/org/onap/aai/it/multitenancy/KeycloakTestProperties.java b/aai-resources/src/test/java/org/onap/aai/it/multitenancy/KeycloakTestProperties.java
deleted file mode 100644 (file)
index 7f1e34c..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.aai.it.multitenancy;
-
-import org.springframework.beans.factory.annotation.Value;
-
-class KeycloakTestProperties {
-
-    @Value("${test.keycloak.realm.json}")
-    public String realmJson;
-
-    @Value("${keycloak.realm}")
-    public String realm;
-
-    @Value("${keycloak.resource}")
-    public String clientId;
-
-    @Value("${test.keycloak.client.secret}")
-    public String clientSecret;
-
-    @Value("${test.keycloak.admin.cli}")
-    public String adminCli;
-
-    @Value("${test.keycloak.auth-server-port}")
-    public String port;
-
-}
diff --git a/aai-resources/src/test/java/org/onap/aai/it/multitenancy/MultiTenancyIT.java b/aai-resources/src/test/java/org/onap/aai/it/multitenancy/MultiTenancyIT.java
deleted file mode 100644 (file)
index 892b8e3..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * ============LICENSE_START==================================================
- * org.onap.aai
- * ===========================================================================
- * Copyright © 2017-2020 AT&T Intellectual Property. All rights reserved.
- * ===========================================================================
- * 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.aai.it.multitenancy;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
-import dasniko.testcontainers.keycloak.KeycloakContainer;
-import org.junit.jupiter.api.Test;
-
-import java.util.Collections;
-
-import org.keycloak.admin.client.Keycloak;
-import org.keycloak.admin.client.KeycloakBuilder;
-import org.keycloak.representations.AccessTokenResponse;
-import org.onap.aai.PayloadUtil;
-import org.onap.aai.rest.AbstractSpringRestTest;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Import;
-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.test.context.TestPropertySource;
-
-@Import(KeycloakTestConfiguration.class)
-@TestPropertySource(locations = "classpath:it/application-keycloak-test.properties")
-public class MultiTenancyIT extends AbstractSpringRestTest {
-
-    @Autowired
-    private KeycloakContainer keycloakContainer;
-    @Autowired
-    private RoleHandler roleHandler;
-    @Autowired
-    private KeycloakTestProperties properties;
-
-    @Test
-    public void testCreateAndGetPnf() throws Exception {
-        baseUrl = "http://localhost:" + randomPort;
-        String endpoint = baseUrl + "/aai/v23/network/pnfs/pnf/pnf-1";
-        ResponseEntity<String> responseEntity = null;
-
-        // create pnf with ran (operator)
-        String username = "ran", password = "ran";
-        headers = this.getHeaders(username, password);
-        httpEntity = new HttpEntity<String>(PayloadUtil.getResourcePayload("pnf.json"), headers);
-        responseEntity = restTemplate.exchange(endpoint, HttpMethod.PUT, httpEntity, String.class);
-        assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode());
-
-        // get pnf with bob (operator_readOnly)
-        username = "bob";
-        password = "bob";
-        headers = this.getHeaders(username, password);
-        httpEntity = new HttpEntity<String>("", headers);
-        responseEntity = restTemplate.exchange(endpoint, HttpMethod.GET, httpEntity, String.class);
-        assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
-
-        // get pnf with ted (selector)
-        username = "ted";
-        password = "ted";
-        headers = this.getHeaders(username, password);
-        httpEntity = new HttpEntity<String>("", headers);
-        responseEntity = restTemplate.exchange(endpoint, HttpMethod.GET, httpEntity, String.class);
-        assertEquals(HttpStatus.FORBIDDEN, responseEntity.getStatusCode());
-
-        // add role to ted and try to get pnf again
-        roleHandler.addToUser(RoleHandler.OPERATOR_READ_ONLY, username);
-        headers = this.getHeaders(username, password);
-        httpEntity = new HttpEntity<String>("", headers);
-        responseEntity = restTemplate.exchange(endpoint, HttpMethod.GET, httpEntity, String.class);
-        assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
-
-        // get pnf with ran
-        username = "ran";
-        password = "ran";
-        headers = this.getHeaders(username, password);
-        httpEntity = new HttpEntity<String>("", headers);
-        responseEntity = restTemplate.exchange(endpoint, HttpMethod.GET, httpEntity, String.class);
-        assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
-    }
-
-    private HttpHeaders getHeaders(String username, String password) {
-        HttpHeaders headers = new HttpHeaders();
-
-        headers.setContentType(MediaType.APPLICATION_JSON);
-        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
-        headers.add("Real-Time", "true");
-        headers.add("X-FromAppId", "JUNIT");
-        headers.add("X-TransactionId", "JUNIT");
-        headers.add("Authorization", "Bearer " + getStringToken(username, password));
-
-        return headers;
-    }
-
-    private String getStringToken(String username, String password) {
-        Keycloak keycloakClient = KeycloakBuilder.builder().serverUrl(keycloakContainer.getAuthServerUrl())
-                .realm(properties.realm).clientId(properties.clientId).clientSecret(properties.clientSecret)
-                .username(username).password(password).build();
-
-        AccessTokenResponse tokenResponse = keycloakClient.tokenManager().getAccessToken();
-        assertNotNull(tokenResponse);
-        return tokenResponse.getToken();
-    }
-}
diff --git a/aai-resources/src/test/java/org/onap/aai/it/multitenancy/RoleHandler.java b/aai-resources/src/test/java/org/onap/aai/it/multitenancy/RoleHandler.java
deleted file mode 100644 (file)
index c9c1fd2..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.aai.it.multitenancy;
-
-import java.util.Collections;
-
-import org.keycloak.admin.client.Keycloak;
-import org.keycloak.admin.client.resource.RealmResource;
-
-class RoleHandler {
-
-    /**
-     * Following roles should be the same as given roles in multi-tenancy-realm json file
-     */
-    final static String OPERATOR = "operator";
-    final static String OPERATOR_READ_ONLY = "operator_readOnly";
-    private final Keycloak adminClient;
-    private final KeycloakTestProperties properties;
-
-    RoleHandler(Keycloak adminClient, KeycloakTestProperties properties) {
-        this.adminClient = adminClient;
-        this.properties = properties;
-    }
-
-    void addToUser(String role, String username) {
-        RealmResource realm = adminClient.realm(properties.realm);
-        realm.users().get(username).roles().realmLevel()
-                .add(Collections.singletonList(realm.roles().get(role).toRepresentation()));
-    }
-
-    void removeFromUser(String role, String username) {
-        RealmResource realm = adminClient.realm(properties.realm);
-        realm.users().get(username).roles().realmLevel()
-                .remove(Collections.singletonList(realm.roles().get(role).toRepresentation()));
-    }
-}
index adfa433..edf905e 100644 (file)
@@ -36,7 +36,6 @@ import org.onap.aai.ResourcesTestConfiguration;
 import org.onap.aai.dbmap.AAIGraph;
 import org.onap.aai.exceptions.AAIException;
 import org.onap.aai.nodes.NodeIngestor;
-import org.onap.aai.restclient.PropertyPasswordConfiguration;
 import org.onap.aai.util.AAIConfig;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@@ -54,7 +53,7 @@ import org.springframework.web.client.RestTemplate;
 
 @Import(ResourcesTestConfiguration.class)
 @TestPropertySource(locations = "classpath:application-test.properties")
-@ContextConfiguration(initializers = PropertyPasswordConfiguration.class)
+@ContextConfiguration
 @EnableAutoConfiguration(exclude = {CassandraDataAutoConfiguration.class, CassandraAutoConfiguration.class}) // there is no running cassandra instance for the test
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = ResourcesApp.class)
 public abstract class AbstractSpringRestTest {
diff --git a/aai-resources/src/test/java/org/onap/aai/rest/AuthenticationTest.java b/aai-resources/src/test/java/org/onap/aai/rest/AuthenticationTest.java
new file mode 100644 (file)
index 0000000..446b375
--- /dev/null
@@ -0,0 +1,78 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.
+ * ================================================================================
+ * 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.aai.rest;
+
+import java.time.Duration;
+import java.util.Collections;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.onap.aai.config.AuthProperties;
+import org.onap.aai.config.WebClientConfiguration;
+import org.onap.aai.setup.SchemaVersions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.web.server.LocalServerPort;
+import org.springframework.context.annotation.Import;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.reactive.server.WebTestClient;
+
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+@Import(WebClientConfiguration.class)
+public class AuthenticationTest {
+
+  @Autowired AuthProperties authProperties;
+  @Autowired SchemaVersions schemaVersions;
+  @LocalServerPort int port;
+
+  WebTestClient webClient;
+
+  @BeforeEach
+  void setup() {
+    webClient = WebTestClient.bindToServer()
+      .baseUrl("http://localhost:" + port + "/aai/" + schemaVersions.getDefaultVersion())
+      .responseTimeout(Duration.ofSeconds(300))
+      .defaultHeaders(headers -> {
+        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
+        headers.set("X-FromAppId", "test");
+        headers.set("X-TransactionId", "someTransaction");
+      })
+      .build();
+  }
+
+  @Test
+  void thatServiceIsAuthenticated() {
+      webClient.get()
+          .uri("/cloud-infrastructure/pservers/pserver/pserver-hostname-test")
+          .exchange()
+          .expectStatus()
+          .isForbidden();
+
+      webClient.get()
+          .uri("/cloud-infrastructure/pservers/pserver/pserver-hostname-test")
+          .headers(headers -> headers.setBasicAuth(authProperties.getUsers().get(0).getUsername(), authProperties.getUsers().get(0).getPassword()))
+          .exchange()
+          .expectStatus()
+          .isNotFound();
+  }
+
+}
index 15c03cf..51ab2aa 100644 (file)
@@ -35,7 +35,6 @@ import org.junit.jupiter.api.Test;
 import org.onap.aai.ResourcesApp;
 import org.onap.aai.ResourcesTestConfiguration;
 import org.onap.aai.config.SpringContextAware;
-import org.onap.aai.restclient.PropertyPasswordConfiguration;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@@ -61,7 +60,7 @@ import org.springframework.web.client.RestTemplate;
 
 @AutoConfigureMetrics
 @TestPropertySource(locations = "classpath:application-test.properties")
-@ContextConfiguration(initializers = PropertyPasswordConfiguration.class, classes = {SpringContextAware.class})
+@ContextConfiguration(classes = {SpringContextAware.class})
 @EnableAutoConfiguration(exclude={CassandraDataAutoConfiguration.class, CassandraAutoConfiguration.class}) // there is no running cassandra instance for the test
 @Import(ResourcesTestConfiguration.class)
 @SpringBootTest(
index da7c064..6d0dcbf 100644 (file)
@@ -99,71 +99,11 @@ import reactor.core.publisher.Mono;
 public class ResourcesControllerTest {
 
     private static final Logger logger = LoggerFactory.getLogger(ResourcesController.class.getName());
-    private static final Set<Integer> VALID_HTTP_STATUS_CODES = new HashSet<>();
-    protected static final MediaType APPLICATION_JSON = MediaType.valueOf("application/json");
-
-    static {
-        VALID_HTTP_STATUS_CODES.add(200);
-        VALID_HTTP_STATUS_CODES.add(201);
-        VALID_HTTP_STATUS_CODES.add(204);
-    }
+    private static final ObjectMapper mapper = new ObjectMapper();
 
     @Autowired WebTestClient webClient;
     @Autowired SchemaVersions schemaVersions;
 
-    ObjectMapper mapper = new ObjectMapper();
-
-    private ResourcesController resourcesController;
-    private HttpHeaders httpHeaders;
-    private UriInfo uriInfo;
-    private MultivaluedMap<String, String> headersMultiMap;
-    private MultivaluedMap<String, String> queryParameters;
-    private List<String> aaiRequestContextList;
-    private List<MediaType> outputMediaTypes;
-    private String defaultSchemaVersion;
-
-    @BeforeEach
-    public void setup() throws AAIException {
-        if(!AAIGraph.isInit()) {
-            AAIConfig.init();
-            AAIGraph.getInstance();
-        }
-        logger.info("Starting the setup for the integration tests of Rest Endpoints");
-
-        resourcesController = new ResourcesController(new ResourcesService());
-        httpHeaders = Mockito.mock(HttpHeaders.class);
-        uriInfo = Mockito.mock(UriInfo.class);
-
-        headersMultiMap = new MultivaluedHashMap<>();
-        queryParameters = Mockito.spy(new MultivaluedHashMap<>());
-
-        headersMultiMap.add("X-FromAppId", "JUNIT");
-        headersMultiMap.add("X-TransactionId", UUID.randomUUID().toString());
-        headersMultiMap.add("Real-Time", "true");
-        headersMultiMap.add("Accept", "application/json");
-        headersMultiMap.add("aai-request-context", "");
-
-        outputMediaTypes = new ArrayList<>();
-        outputMediaTypes.add(APPLICATION_JSON);
-
-        aaiRequestContextList = new ArrayList<>();
-        aaiRequestContextList.add("");
-        defaultSchemaVersion = schemaVersions.getDefaultVersion().toString();
-
-        when(httpHeaders.getAcceptableMediaTypes()).thenReturn(outputMediaTypes);
-        when(httpHeaders.getRequestHeaders()).thenReturn(headersMultiMap);
-
-        when(httpHeaders.getRequestHeader("aai-request-context")).thenReturn(aaiRequestContextList);
-
-        when(uriInfo.getQueryParameters()).thenReturn(queryParameters);
-        when(uriInfo.getQueryParameters(false)).thenReturn(queryParameters);
-
-        // TODO - Check if this is valid since RemoveDME2QueryParameters seems to be very unreasonable
-        Mockito.doReturn(null).when(queryParameters).remove(any());
-
-        when(httpHeaders.getMediaType()).thenReturn(APPLICATION_JSON);
-    }
-
     @AfterEach
     public void tearDown() {
         JanusGraph janusGraph = AAIGraph.getInstance().getGraph();
@@ -423,11 +363,6 @@ public class ResourcesControllerTest {
 
         String patchData = "{\"in-maint\": false}";
 
-        headersMultiMap.add("Content-Type", "application/json");
-
-        outputMediaTypes.remove(APPLICATION_JSON);
-        outputMediaTypes.add(MediaType.valueOf("application/merge-patch+json"));
-
         webClient.patch()
             .uri(uri)
             .header("Content-Type", "application/merge-patch+json")
@@ -496,12 +431,12 @@ public class ResourcesControllerTest {
 
     public String getResourcePayload(String resourceName) throws IOException {
         String rawPayload = IOUtils.toString(this.getClass().getResourceAsStream("/payloads/resource/" + resourceName + ".json"), StandardCharsets.UTF_8);
-        return String.format(rawPayload, defaultSchemaVersion);
+        return String.format(rawPayload, schemaVersions.getDefaultVersion());
     }
 
     public String getRelationshipPayload(String relationshipName) throws IOException {
         String rawPayload = IOUtils.toString(this.getClass().getResourceAsStream("/payloads/relationship/" + relationshipName + ".json"), StandardCharsets.UTF_8);
-        return String.format(rawPayload, defaultSchemaVersion);
+        return String.format(rawPayload, schemaVersions.getDefaultVersion());
     }
 
     public String getUri(String hostname) {
index 622715d..e2b11ad 100644 (file)
@@ -16,7 +16,6 @@ spring.sleuth.enabled=false
 spring.autoconfigure.exclude=\
   org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
   org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
-  org.keycloak.adapters.springboot.KeycloakAutoConfiguration,\
   org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
   org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration
 
@@ -28,17 +27,7 @@ server.tomcat.threads.min-spare=25
 server.tomcat.max-idle-time=60000
 
 server.local.startpath=src/main/resources/
-server.basic.auth.location=${server.local.startpath}etc/auth/realm.properties
-
 server.port=8447
-server.ssl.enabled=false
-#server.ssl.enabled-protocols=TLSv1.1,TLSv1.2
-#server.ssl.key-store=${server.local.startpath}etc/auth/aai_keystore
-#server.ssl.key-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
-#server.ssl.trust-store=${server.local.startpath}etc/auth/aai_keystore
-#server.ssl.trust-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
-#server.ssl.client-auth=want
-#server.ssl.key-store-type=JKS
 
 # Removed deprecated DMaaP reference
 # dmaap.ribbon.listOfServers=localhost:3904
@@ -82,3 +71,6 @@ scrape.uri.metrics=true
 
 aai.notifications.enabled=false
 aai.graph.properties.path=src/test/resources/etc/appprops/janusgraph-realtime.properties
+aai.basic-auth.enabled=true
+aai.basic-auth.users[0].username=AAI
+aai.basic-auth.users[0].password=AAI
diff --git a/aai-resources/src/test/resources/it/application-keycloak-test.properties b/aai-resources/src/test/resources/it/application-keycloak-test.properties
deleted file mode 100644 (file)
index 6fff1c1..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-test.keycloak.realm.json=it/multi-tenancy-realm.json
-test.keycloak.client.secret=secret
-test.keycloak.admin.cli=admin-cli
-test.keycloak.auth-server-port=58180
-
-keycloak.auth-server-url=http://localhost:58180/auth
-keycloak.realm=aai-resources
-keycloak.resource=aai-resources-app
-keycloak.public-client=true
-keycloak.principal-attribute=preferred_username
-
-keycloak.ssl-required=external
-keycloak.bearer-only=true
-
-multi.tenancy.enabled=true
-spring.profiles.active=production,keycloak
-schema.version.list=v10,v11,v12,v13,v14,v29,v30
diff --git a/aai-resources/src/test/resources/it/multi-tenancy-realm.json b/aai-resources/src/test/resources/it/multi-tenancy-realm.json
deleted file mode 100644 (file)
index 401187b..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-{
-    "id": "aai-resources",
-    "realm": "aai-resources",
-    "notBefore": 0,
-    "revokeRefreshToken": false,
-    "refreshTokenMaxReuse": 0,
-    "accessTokenLifespan": 300,
-    "accessTokenLifespanForImplicitFlow": 900,
-    "ssoSessionIdleTimeout": 1800,
-    "ssoSessionMaxLifespan": 36000,
-    "ssoSessionIdleTimeoutRememberMe": 0,
-    "ssoSessionMaxLifespanRememberMe": 0,
-    "offlineSessionIdleTimeout": 2592000,
-    "offlineSessionMaxLifespanEnabled": false,
-    "offlineSessionMaxLifespan": 5184000,
-    "clientSessionIdleTimeout": 0,
-    "clientSessionMaxLifespan": 0,
-    "clientOfflineSessionIdleTimeout": 0,
-    "clientOfflineSessionMaxLifespan": 0,
-    "accessCodeLifespan": 60,
-    "accessCodeLifespanUserAction": 300,
-    "accessCodeLifespanLogin": 1800,
-    "actionTokenGeneratedByAdminLifespan": 43200,
-    "actionTokenGeneratedByUserLifespan": 300,
-    "enabled": true,
-    "sslRequired": "external",
-    "registrationAllowed": false,
-    "registrationEmailAsUsername": false,
-    "rememberMe": false,
-    "verifyEmail": false,
-    "loginWithEmailAllowed": true,
-    "duplicateEmailsAllowed": false,
-    "resetPasswordAllowed": false,
-    "editUsernameAllowed": false,
-    "bruteForceProtected": false,
-    "permanentLockout": false,
-    "maxFailureWaitSeconds": 900,
-    "minimumQuickLoginWaitSeconds": 60,
-    "waitIncrementSeconds": 60,
-    "quickLoginCheckMilliSeconds": 1000,
-    "maxDeltaTimeSeconds": 43200,
-    "failureFactor": 30,
-    "users": [
-        {
-            "username": "admin",
-            "enabled": true,
-            "credentials": [
-                {
-                    "type": "password",
-                    "value": "admin"
-                }
-            ],
-            "clientRoles": {
-                "realm-management": ["manage-users", "view-clients", "view-realm", "view-users"]
-            }
-        },
-        {
-            "id": "ran",
-            "username": "ran",
-            "enabled": true,
-            "credentials": [
-                {
-                    "type": "password",
-                    "value": "ran"
-                }
-            ],
-            "realmRoles": [
-                "operator"
-            ]
-        },
-        {
-            "id": "bob",
-            "username": "bob",
-            "enabled": true,
-            "credentials": [
-                {
-                    "type": "password",
-                    "value": "bob"
-                }
-            ],
-            "realmRoles": [
-                "operator_readOnly"
-            ]
-        },
-        {
-            "id": "ted",
-            "username": "ted",
-            "enabled": true,
-            "credentials": [
-                {
-                    "type": "password",
-                    "value": "ted"
-                }
-            ],
-            "realmRoles": [
-                "selector"
-            ]
-        }
-    ],
-    "roles": {
-        "realm": [
-            {
-                "name": "operator",
-                "description": "Operator privileges"
-            },
-            {
-                "name": "operator_readOnly",
-                "description": "Operator's read only privileges"
-            },
-            {
-                "name": "selector",
-                "description": "Selector privileges"
-            },
-            {
-                "name": "selector_readOnly",
-                "description": "Selector's read only privileges"
-            },
-            {
-                "name": "admin",
-                "description": "Administrator privileges"
-            }
-        ]
-    },
-    "clients": [
-        {
-            "clientId": "aai-resources-app",
-            "enabled": true,
-            "secret": "secret",
-            "directAccessGrantsEnabled": true,
-            "authorizationServicesEnabled": true,
-            "authorizationSettings": {
-                "allowRemoteResourceManagement": true,
-                "policyEnforcementMode": "ENFORCING"
-            }
-        }
-    ],
-    "defaultDefaultClientScopes": [
-        "roles",
-        "email",
-        "web-origins",
-        "profile",
-        "role_list"
-    ],
-    "clientScopes": [
-        {
-            "id": "0f7dfd8b-c230-4664-8d77-da85bcc4fe2a",
-            "name": "roles",
-            "description": "OpenID Connect scope for add user roles to the access token",
-            "protocol": "openid-connect",
-            "attributes": {
-                "include.in.token.scope": "true",
-                "display.on.consent.screen": "true",
-                "consent.screen.text": "${rolesScopeConsentText}"
-            },
-            "protocolMappers": [
-                {
-                    "id": "4b9f8798-8990-4c0d-87d3-034e72655e3b",
-                    "name": "realm roles",
-                    "protocol": "openid-connect",
-                    "protocolMapper": "oidc-usermodel-realm-role-mapper",
-                    "consentRequired": false,
-                    "config": {
-                        "multivalued": "true",
-                        "user.attribute": "foo",
-                        "access.token.claim": "true",
-                        "claim.name": "realm_access.roles",
-                        "jsonType.label": "String"
-                    }
-                }
-            ]
-        }
-    ]
-}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index c1d916a..7a63d2b 100644 (file)
--- a/pom.xml
+++ b/pom.xml
     <parent>
         <groupId>org.onap.aai.aai-common</groupId>
         <artifactId>aai-parent</artifactId>
-        <version>1.15.4</version>
+        <version>1.15.5-SNAPSHOT</version>
     </parent>
     <groupId>org.onap.aai.resources</groupId>
     <artifactId>resources</artifactId>
-    <version>1.15.4-SNAPSHOT</version>
+    <version>1.15.5-SNAPSHOT</version>
     <name>aai-resources</name>
     <packaging>pom</packaging>
     <modules>
@@ -49,7 +49,7 @@
         <staging.path>/content/repositories/staging/</staging.path>
         <!-- GMaven plugin uses this property to figure out the name of the docker tag -->
         <aai.project.version>${project.version}</aai.project.version>
-        <aai.common.version>1.15.4</aai.common.version>
+        <aai.common.version>1.15.5-SNAPSHOT</aai.common.version>
         <aai.schema.service.version>1.12.7</aai.schema.service.version>
     </properties>
     <build>
index 08fc17c..73ddb41 100644 (file)
@@ -5,7 +5,7 @@
 
 major_version=1
 minor_version=15
-patch_version=3
+patch_version=5
 
 base_version=${major_version}.${minor_version}.${patch_version}