You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@amoro.apache.org by ji...@apache.org on 2025/03/19 03:58:12 UTC

(amoro) branch master updated: [AMORO-3446] Fix Amoro pod liveness check failed due to authenticate error (#3465)

This is an automated email from the ASF dual-hosted git repository.

jinsongzhou pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/amoro.git


The following commit(s) were added to refs/heads/master by this push:
     new 3b8eefdb3 [AMORO-3446] Fix Amoro pod liveness check failed due to authenticate error (#3465)
3b8eefdb3 is described below

commit 3b8eefdb3868b1a1b520aa12408aff244ce71315
Author: Marvel-Gu <17...@qq.com>
AuthorDate: Wed Mar 19 03:58:08 2025 +0000

    [AMORO-3446] Fix Amoro pod liveness check failed due to authenticate error (#3465)
    
    * fix: Amoro pod liveness check failed due to authenticate error
    
    * refactor: optimize code logic, improve readability and maintainability
    
    * Test: Add unit tests for DashboardServer
    
    * Test: fix TestDashboardServer format error
    
    * Fix Checkstyle issue: avoid wildcard import in TestDashboardServer.java
    
    * Fix Checkstyle issue
    
    * Fix NullPointerException
    
    * Fix Checkstyle issue
    
    * fix MissingMethodInvocation
    
    * Test: delete unit tests for DashboardServer
---
 .../amoro/server/dashboard/DashboardServer.java    | 98 +++++++++++-----------
 1 file changed, 47 insertions(+), 51 deletions(-)

diff --git a/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/DashboardServer.java b/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/DashboardServer.java
index a66c9feb6..b5e71bc16 100644
--- a/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/DashboardServer.java
+++ b/amoro-ams/src/main/java/org/apache/amoro/server/dashboard/DashboardServer.java
@@ -78,8 +78,6 @@ public class DashboardServer {
   private static final String AUTH_TYPE_BASIC = "basic";
   private static final String X_REQUEST_SOURCE_HEADER = "X-Request-Source";
   private static final String X_REQUEST_SOURCE_WEB = "Web";
-  private static final String SWAGGER_PATH = "/openapi-ui";
-
   private final CatalogController catalogController;
   private final HealthCheckController healthCheckController;
   private final LoginController loginController;
@@ -128,31 +126,32 @@ public class DashboardServer {
     this.basicAuthPassword = serviceConfig.get(AmoroManagementConf.ADMIN_PASSWORD);
   }
 
-  private String indexHtml = "";
+  private volatile String indexHtml = null;
   // read index.html content
   public String getIndexFileContent() {
-    try {
-      if ("".equals(indexHtml)) {
-        try (InputStream fileName =
-            DashboardServer.class.getClassLoader().getResourceAsStream("static/index.html")) {
-          Preconditions.checkNotNull(fileName, "Cannot find index file.");
-          try (InputStreamReader isr =
-                  new InputStreamReader(fileName, StandardCharsets.UTF_8.newDecoder());
-              BufferedReader br = new BufferedReader(isr)) {
-            StringBuilder sb = new StringBuilder();
-            String line;
-            while ((line = br.readLine()) != null) {
-              // process the line
-              sb.append(line);
+    if (indexHtml == null) {
+      synchronized (this) {
+        if (indexHtml == null) {
+          try (InputStream inputStream =
+              DashboardServer.class.getClassLoader().getResourceAsStream("static/index.html")) {
+            Preconditions.checkNotNull(inputStream, "Cannot find index file.");
+            try (InputStreamReader isr =
+                    new InputStreamReader(inputStream, StandardCharsets.UTF_8);
+                BufferedReader br = new BufferedReader(isr)) {
+              StringBuilder sb = new StringBuilder();
+              String line;
+              while ((line = br.readLine()) != null) {
+                sb.append(line);
+              }
+              indexHtml = sb.toString();
             }
-            indexHtml = sb.toString();
+          } catch (IOException e) {
+            throw new UncheckedIOException("Load index html failed", e);
           }
         }
       }
-      return indexHtml;
-    } catch (IOException e) {
-      throw new UncheckedIOException("Load index html failed", e);
     }
+    return indexHtml;
   }
 
   public Consumer<StaticFileConfig> configStaticFiles() {
@@ -378,26 +377,28 @@ public class DashboardServer {
 
   public void preHandleRequest(Context ctx) {
     String uriPath = ctx.path();
-    String requestSource = ctx.header(X_REQUEST_SOURCE_HEADER);
-    if (uriPath.startsWith(SWAGGER_PATH)) {
+    if (inWhiteList(uriPath)) {
       return;
     }
-    if (needApiKeyCheck(uriPath) && !X_REQUEST_SOURCE_WEB.equalsIgnoreCase(requestSource)) {
-      if (AUTH_TYPE_BASIC.equalsIgnoreCase(authType)) {
-        BasicAuthCredentials cred = ctx.basicAuthCredentials();
-        if (!(basicAuthUser.equals(cred.component1())
-            && basicAuthPassword.equals(cred.component2()))) {
-          throw new SignatureCheckException(
-              "Failed to authenticate via basic authentication for url:" + uriPath);
-        }
-      } else {
-        checkApiToken(
-            ctx.url(), ctx.queryParam("apiKey"), ctx.queryParam("signature"), ctx.queryParamMap());
-      }
-    } else if (needLoginCheck(uriPath)) {
+    String requestSource = ctx.header(X_REQUEST_SOURCE_HEADER);
+    boolean isWebRequest = X_REQUEST_SOURCE_WEB.equalsIgnoreCase(requestSource);
+
+    if (isWebRequest) {
       if (null == ctx.sessionAttribute("user")) {
         throw new ForbiddenException("User session attribute is missed for url: " + uriPath);
       }
+      return;
+    }
+    if (AUTH_TYPE_BASIC.equalsIgnoreCase(authType)) {
+      BasicAuthCredentials cred = ctx.basicAuthCredentials();
+      if (!(basicAuthUser.equals(cred.component1())
+          && basicAuthPassword.equals(cred.component2()))) {
+        throw new SignatureCheckException(
+            "Failed to authenticate via basic authentication for url:" + uriPath);
+      }
+    } else {
+      checkApiToken(
+          ctx.url(), ctx.queryParam("apiKey"), ctx.queryParam("signature"), ctx.queryParamMap());
     }
   }
 
@@ -417,7 +418,7 @@ public class DashboardServer {
     LOG.error("An error occurred while processing the url:{}", ctx.url(), e);
   }
 
-  private static final String[] urlWhiteList = {
+  private static final String[] URL_WHITE_LIST = {
     "/api/ams/v1/versionInfo",
     "/api/ams/v1/login",
     "/api/ams/v1/health/status",
@@ -440,23 +441,19 @@ public class DashboardServer {
     RestCatalogService.ICEBERG_REST_API_PREFIX + "/*"
   };
 
-  private static boolean needLoginCheck(String uri) {
-    for (String item : urlWhiteList) {
+  private static boolean inWhiteList(String uri) {
+    for (String item : URL_WHITE_LIST) {
       if (item.endsWith("*")) {
         if (uri.startsWith(item.substring(0, item.length() - 1))) {
-          return false;
+          return true;
         }
       } else {
         if (uri.equals(item)) {
-          return false;
+          return true;
         }
       }
     }
-    return true;
-  }
-
-  private boolean needApiKeyCheck(String uri) {
-    return uri.startsWith("/api/ams");
+    return false;
   }
 
   private void checkApiToken(
@@ -465,16 +462,15 @@ public class DashboardServer {
     String encryptString;
     String signCal;
 
-    APITokenManager apiTokenService = new APITokenManager();
     try {
+      if (apiKey == null || signature == null) {
+        throw new SignatureCheckException("API key or signature is missing");
+      }
+      APITokenManager apiTokenService = new APITokenManager();
       String secret = apiTokenService.getSecretByKey(apiKey);
 
       if (secret == null) {
-        throw new SignatureCheckException();
-      }
-
-      if (apiKey == null || signature == null) {
-        throw new SignatureCheckException();
+        throw new SignatureCheckException("Invalid API key");
       }
 
       params.remove("apiKey");