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

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git


The following commit(s) were added to refs/heads/master by this push:
     new 03c37b2   [SCB-2114]support RBAC of service center and provider 
bootstrap extentions (#2039)
03c37b2 is described below

commit 03c37b2edf1ee5dc79921cbe5d3429121f144827
Author: bao liu <[email protected]>
AuthorDate: Thu Nov 5 15:53:06 2020 +0800

     [SCB-2114]support RBAC of service center and provider bootstrap extentions 
(#2039)
    
    * [SCB-2114]support RBAC of service center and provider bootstrap extentions
    
    * [SCB-2114]add ak/sk cipher support and enable ak/sk in solution basic
    
    * [SCB-2114]add license
    
    * [SCB-2114]fix comments
    
    * [SCB-2114] ak/sk enabled but access key not configured add a warning.
    
    * [SCB-2114] add spi boot file
    
    * [SCB-2114] add config center to solution
    
    * [SCB-2114] fix spelling
---
 clients/http-client-common/pom.xml                 |   5 +
 .../auth/DefaultRequestAuthHeaderProvider.java     |  13 +-
 .../client/auth/RequestAuthHeaderProvider.java     |   8 +-
 .../http/client/common/HttpConfiguration.java      |  59 -------
 .../http/client/common/HttpTransportFactory.java   |   5 +-
 .../http/client/common/HttpTransportImpl.java      |  17 +-
 .../client/common/auth/AKSKHeaderExtension.java    |  86 ---------
 .../http/client/common/auth/AKSKHeaderUtil.java    |  48 -----
 .../auth/FileSystemMountAKSKHeaderExtension.java   |  97 -----------
 .../http/client/common/HttpTransportImplTest.java  |   8 +-
 .../service/center/client/AddressManager.java      |   8 +-
 .../service/center/client/ServiceCenterClient.java |  38 +++-
 .../center/client/ServiceCenterOperation.java      |  10 ++
 .../center/client/ServiceCenterRawClient.java      |  19 +-
 .../center/client/model}/RbacTokenRequest.java     |  17 +-
 .../center/client/model}/RbacTokenResponse.java    |  13 +-
 .../core/ConfigurationSpringInitializer.java       |  80 ++++++---
 coverage-reports/pom.xml                           |   4 +
 .../IConfigurationEndpoint.java                    |   8 +-
 .../RegistryClientTest.java                        |   8 +-
 .../demo/multiServiceCenterClient/ServerBTest.java |  16 ++
 .../ConfigurationEndpoint.java                     |  76 ++++++++
 .../src/main/resources/application.yml             |   7 +-
 .../src/main/resources/microservice.yaml           |  11 +-
 .../java/org/apache/servicecomb/demo/TestMgr.java  |  13 ++
 .../src/main/resources/microservice.yaml           |   7 +-
 dependencies/bom/pom.xml                           |   5 +
 distribution/pom.xml                               |   4 +
 .../config/client/ConfigCenterClient.java          |  18 +-
 foundations/foundation-common/pom.xml              |   5 +
 .../servicecomb/foundation/auth/DefaultCipher.java |   4 +-
 ...{AuthHeaderProvider.java => ShaAKSKCipher.java} |  15 +-
 foundations/{ => foundation-spi}/pom.xml           |  29 ++--
 .../foundation/auth/AuthHeaderLoader.java          |  29 ++--
 .../foundation/auth/AuthHeaderProvider.java        |   0
 .../servicecomb/foundation/auth/SignRequest.java   |   0
 .../foundation/bootstrap/BootStrapService.java}    |  15 +-
 .../foundation/common/utils/SPIEnabled.java        |   0
 .../foundation/common/utils/SPIOrder.java          |   0
 .../foundation/common/utils/SPIServiceUtils.java   |   0
 .../foundation/common/utils/SPIServiceDef.java     |   0
 .../foundation/common/utils/SPIServiceDef0.java    |   0
 .../common/utils/SPIServiceDef0Impl.java           |   0
 .../foundation/common/utils/SPIServiceDefImpl.java |   0
 .../common/utils/TestSPIServiceUtils.java          |   0
 ...rvicecomb.foundation.common.utils.SPIServiceDef |   0
 .../servicecomb/foundation/ssl/SSLOption.java      |   2 +-
 foundations/pom.xml                                |   1 +
 .../servicestage/AKSKAuthHeaderProvider.java       | 142 +++++++++++++++
 ....servicecomb.foundation.auth.AuthHeaderProvider |   2 +-
 service-registry/registry-service-center/pom.xml   |   5 +
 .../serviceregistry/auth/RBACBootStrapService.java | 193 +++++++++++++++++++++
 .../auth/TokenAuthHeaderProvider.java              |  53 +-----
 .../serviceregistry/auth/TokenCacheManager.java    |  36 ++--
 .../client/ServiceRegistryClient.java              |   4 -
 .../client/http/ServiceRegistryClientImpl.java     |  37 ----
 ...rvicecomb.foundation.bootstrap.BootStrapService |   2 +-
 .../client/LocalServiceRegistryClientImpl.java     |   7 -
 .../client/http/TestServiceRegistryClientImpl.java | 104 -----------
 solutions/solution-basic/pom.xml                   |   8 +-
 60 files changed, 736 insertions(+), 665 deletions(-)

diff --git a/clients/http-client-common/pom.xml 
b/clients/http-client-common/pom.xml
index b1654d8..62ad013 100644
--- a/clients/http-client-common/pom.xml
+++ b/clients/http-client-common/pom.xml
@@ -63,6 +63,11 @@
     </dependency>
 
     <dependency>
+      <groupId>org.apache.servicecomb</groupId>
+      <artifactId>foundation-spi</artifactId>
+    </dependency>
+
+    <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <scope>test</scope>
diff --git 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderProvider.java
 
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/auth/DefaultRequestAuthHeaderProvider.java
similarity index 76%
copy from 
foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderProvider.java
copy to 
clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/auth/DefaultRequestAuthHeaderProvider.java
index 313c19e..a701a53 100644
--- 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderProvider.java
+++ 
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/auth/DefaultRequestAuthHeaderProvider.java
@@ -15,17 +15,16 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.foundation.auth;
+package org.apache.servicecomb.http.client.auth;
 
 import java.util.HashMap;
 import java.util.Map;
 
-public interface AuthHeaderProvider {
-  default Map<String, String> authHeaders() {
-    return new HashMap<>(0);
-  }
+import org.apache.servicecomb.foundation.auth.SignRequest;
 
-  default Map<String, String> getSignAuthHeaders(SignRequest request) {
-    return authHeaders();
+public class DefaultRequestAuthHeaderProvider implements 
RequestAuthHeaderProvider {
+  @Override
+  public Map<String, String> loadAuthHeader(SignRequest signRequest) {
+    return new HashMap<>(0);
   }
 }
diff --git 
a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef0Impl.java
 
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/auth/RequestAuthHeaderProvider.java
similarity index 77%
copy from 
foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef0Impl.java
copy to 
clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/auth/RequestAuthHeaderProvider.java
index 08cd5a3..131bea7 100644
--- 
a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef0Impl.java
+++ 
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/auth/RequestAuthHeaderProvider.java
@@ -15,8 +15,12 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.foundation.common.utils;
+package org.apache.servicecomb.http.client.auth;
 
-public class SPIServiceDef0Impl implements SPIServiceDef0 {
+import java.util.Map;
 
+import org.apache.servicecomb.foundation.auth.SignRequest;
+
+public interface RequestAuthHeaderProvider {
+  Map<String, String> loadAuthHeader(SignRequest signRequest);
 }
diff --git 
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpConfiguration.java
 
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpConfiguration.java
index b233488..59b6b4c 100644
--- 
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpConfiguration.java
+++ 
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpConfiguration.java
@@ -52,63 +52,4 @@ public interface HttpConfiguration {
       this.sslCustom = sslCustom;
     }
   }
-
-  class AKSKProperties {
-    private boolean enabled;
-
-    private String accessKey;
-
-    private String secretKey;
-
-    private String cipher;
-
-    private String project;
-
-    public boolean isEnabled() {
-      return enabled;
-    }
-
-    public void setEnabled(boolean enabled) {
-      this.enabled = enabled;
-    }
-
-    public String getAccessKey() {
-      return accessKey;
-    }
-
-    public void setAccessKey(String accessKey) {
-      this.accessKey = accessKey;
-    }
-
-    public String getSecretKey() {
-      if ("ShaAKSKCipher".equalsIgnoreCase(this.cipher)) {
-        return this.secretKey;
-      }
-      try {
-        return HttpUtils.sha256Encode(this.secretKey, this.accessKey);
-      } catch (Exception e) {
-        throw new IllegalArgumentException("not able to encode ak sk.", e);
-      }
-    }
-
-    public void setSecretKey(String secretKey) {
-      this.secretKey = secretKey;
-    }
-
-    public String getCipher() {
-      return cipher;
-    }
-
-    public void setCipher(String cipher) {
-      this.cipher = cipher;
-    }
-
-    public String getProject() {
-      return project;
-    }
-
-    public void setProject(String project) {
-      this.project = project;
-    }
-  }
 }
diff --git 
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportFactory.java
 
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportFactory.java
index f9c7b6c..2a2ee92 100644
--- 
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportFactory.java
+++ 
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportFactory.java
@@ -27,6 +27,7 @@ import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
 import org.apache.http.impl.client.HttpClientBuilder;
 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
 import org.apache.servicecomb.foundation.ssl.SSLManager;
+import org.apache.servicecomb.http.client.auth.RequestAuthHeaderProvider;
 
 public class HttpTransportFactory {
   // All parameters set to 5 seconds now.
@@ -44,7 +45,7 @@ public class HttpTransportFactory {
   }
 
   public static HttpTransport 
createHttpTransport(HttpConfiguration.SSLProperties sslProperties,
-      HttpConfiguration.AKSKProperties akskProperties) {
+      RequestAuthHeaderProvider requestAuthHeaderProvider) {
     RequestConfig config = RequestConfig.custom()
         .setConnectTimeout(CONNECT_TIMEOUT)
         .setConnectionRequestTimeout(
@@ -73,6 +74,6 @@ public class HttpTransportFactory {
         setConnectionManager(connectionManager).
         disableCookieManagement();
 
-    return new HttpTransportImpl(httpClientBuilder.build(), akskProperties);
+    return new HttpTransportImpl(httpClientBuilder.build(), 
requestAuthHeaderProvider);
   }
 }
diff --git 
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportImpl.java
 
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportImpl.java
index 7019d87..4f58dab 100644
--- 
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportImpl.java
+++ 
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportImpl.java
@@ -22,8 +22,8 @@ import java.util.Map;
 
 import org.apache.http.client.HttpClient;
 import org.apache.http.util.EntityUtils;
-import 
org.apache.servicecomb.http.client.common.HttpConfiguration.AKSKProperties;
-import org.apache.servicecomb.http.client.common.auth.AKSKHeaderUtil;
+import org.apache.servicecomb.foundation.auth.SignRequest;
+import org.apache.servicecomb.http.client.auth.RequestAuthHeaderProvider;
 
 /**
  * Created by   on 2019/10/16.
@@ -38,11 +38,11 @@ public class HttpTransportImpl implements HttpTransport {
 
   private Map<String, String> globalHeaders;
 
-  private AKSKProperties akskProperties;
+  private RequestAuthHeaderProvider requestAuthHeaderProvider;
 
-  public HttpTransportImpl(HttpClient httpClient, AKSKProperties 
akskProperties) {
+  public HttpTransportImpl(HttpClient httpClient, RequestAuthHeaderProvider 
requestAuthHeaderProvider) {
     this.httpClient = httpClient;
-    this.akskProperties = akskProperties;
+    this.requestAuthHeaderProvider = requestAuthHeaderProvider;
   }
 
   public HttpClient getHttpClient() {
@@ -87,7 +87,7 @@ public class HttpTransportImpl implements HttpTransport {
       globalHeaders.forEach(httpRequest::addHeader);
     }
 
-    AKSKHeaderUtil.addAKSKHeader(httpRequest, akskProperties);
+    
httpRequest.getHeaders().putAll(requestAuthHeaderProvider.loadAuthHeader(createSignRequest()));
 
     //get Http response
     org.apache.http.HttpResponse response = 
httpClient.execute(httpRequest.getRealRequest());
@@ -98,6 +98,11 @@ public class HttpTransportImpl implements HttpTransport {
         response.getAllHeaders());
   }
 
+  private static SignRequest createSignRequest() {
+    // Now the implementations do not process SignRequest, so return null. 
Maybe future will use it.
+    return null;
+  }
+
   @Override
   public void addHeaders(Map<String, String> headers) {
     this.globalHeaders = headers;
diff --git 
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/AKSKHeaderExtension.java
 
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/AKSKHeaderExtension.java
deleted file mode 100644
index 85afa7b..0000000
--- 
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/AKSKHeaderExtension.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-package org.apache.servicecomb.http.client.common.auth;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-public abstract class AKSKHeaderExtension {
-
-  private static final Logger LOGGER = 
LoggerFactory.getLogger(AKSKHeaderExtension.class);
-
-  protected static final String DEFAULT_SECRET_AUTH_PATH = "/opt/CSE/etc/auth";
-
-  protected static final String DEFAULT_SECRET_AUTH_NAME = ".dockerconfigjson";
-
-  private static final int EXPECTED_ARR_LENGTH = 2;
-
-  private boolean runOverHWC = 
!StringUtils.isEmpty(System.getenv("KUBERNETES_SERVICE_HOST"));
-
-  private Map<String, String> defaultAuthHeaders = Collections.emptyMap();
-
-  private boolean loaded = false;
-
-  protected Map<String, String> getHeaders() {
-    if (!runOverHWC) {
-      return defaultAuthHeaders;
-    }
-    if (!loaded) {
-      synchronized (this) {
-        if (!loaded) {
-          createAuthHeaders();
-        }
-      }
-    }
-    return defaultAuthHeaders;
-  }
-
-  public abstract void createAuthHeaders();
-
-  protected void decode(JsonNode authNode) throws IOException {
-    if (authNode == null) {
-      return;
-    }
-    Map<String, String> authHeaders = new HashMap<String, String>();
-    String authStr = authNode.asText();
-    String authBase64Decode = new String(Base64.decodeBase64(authStr), 
"UTF-8");
-    String[] auths = authBase64Decode.split("@");
-    String[] akAndShaAkSk = auths[1].split(":");
-    if (auths.length != EXPECTED_ARR_LENGTH || akAndShaAkSk.length != 
EXPECTED_ARR_LENGTH) {
-      LOGGER.error("get docker config failed. The data is not valid cause of 
unexpected format");
-      return;
-    }
-    String project = auths[0];
-    String ak = akAndShaAkSk[0];
-    String shaAkSk = akAndShaAkSk[1];
-    authHeaders.put("X-Service-AK", ak);
-    authHeaders.put("X-Service-ShaAKSK", shaAkSk);
-    authHeaders.put("X-Service-Project", project);
-    defaultAuthHeaders = authHeaders;
-    loaded = true;
-  }
-}
diff --git 
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/AKSKHeaderUtil.java
 
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/AKSKHeaderUtil.java
deleted file mode 100644
index da4d564..0000000
--- 
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/AKSKHeaderUtil.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-package org.apache.servicecomb.http.client.common.auth;
-
-import java.util.Map;
-
-import 
org.apache.servicecomb.http.client.common.HttpConfiguration.AKSKProperties;
-import org.apache.servicecomb.http.client.common.HttpRequest;
-
-public class AKSKHeaderUtil {
-  public static final String X_SERVICE_AK = "X-Service-AK";
-
-  public static final String X_SERVICE_SHAAKSK = "X-Service-ShaAKSK";
-
-  public static final String X_SERVICE_PROJECT = "X-Service-Project";
-
-  public static void addAKSKHeader(HttpRequest httpRequest,
-      AKSKProperties serviceCombAkSkProperties) {
-    if (serviceCombAkSkProperties.isEnabled()) {
-      httpRequest.addHeader(X_SERVICE_AK, 
serviceCombAkSkProperties.getAccessKey());
-      httpRequest.addHeader(X_SERVICE_SHAAKSK, 
serviceCombAkSkProperties.getSecretKey());
-      httpRequest.addHeader(X_SERVICE_PROJECT, 
serviceCombAkSkProperties.getProject());
-      return;
-    }
-
-    Map<String, String> headerMap = AKSKHeaderExtensionUtil.genAuthHeaders();
-    if (!headerMap.isEmpty()) {
-      httpRequest.addHeader(X_SERVICE_AK, headerMap.get(X_SERVICE_AK));
-      httpRequest.addHeader(X_SERVICE_SHAAKSK, 
headerMap.get(X_SERVICE_SHAAKSK));
-      httpRequest.addHeader(X_SERVICE_PROJECT, 
headerMap.get(X_SERVICE_PROJECT));
-    }
-  }
-}
diff --git 
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/FileSystemMountAKSKHeaderExtension.java
 
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/FileSystemMountAKSKHeaderExtension.java
deleted file mode 100644
index 0a4256b..0000000
--- 
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/FileSystemMountAKSKHeaderExtension.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-package org.apache.servicecomb.http.client.common.auth;
-
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardWatchEventKinds;
-import java.nio.file.WatchKey;
-import java.nio.file.WatchService;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import org.apache.servicecomb.http.client.common.HttpUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-public class FileSystemMountAKSKHeaderExtension extends AKSKHeaderExtension {
-
-  private static final Logger LOGGER = 
LoggerFactory.getLogger(FileSystemMountAKSKHeaderExtension.class);
-
-  private ExecutorService executor = Executors.newFixedThreadPool(1);
-
-  public FileSystemMountAKSKHeaderExtension() {
-    try {
-      Path p = Paths.get(DEFAULT_SECRET_AUTH_PATH);
-      if (!p.toFile().exists()) {
-        return;
-      }
-      WatchService watchService = FileSystems.getDefault().newWatchService();
-      p.register(watchService,
-          StandardWatchEventKinds.ENTRY_MODIFY,
-          StandardWatchEventKinds.ENTRY_CREATE);
-      executor.execute(new FileUpdateCheckThread(watchService));
-    } catch (Exception e) {
-      LOGGER.warn("get watch service failed.", e);
-    }
-  }
-
-  @Override
-  public void createAuthHeaders() {
-    try {
-      String content = new String(
-          Files.readAllBytes(Paths.get(DEFAULT_SECRET_AUTH_PATH, 
DEFAULT_SECRET_AUTH_NAME)),
-          "UTF-8");
-      JsonNode data = HttpUtils.readTree(content);
-      JsonNode authNode = data.findValue("auth");
-      decode(authNode);
-    } catch (Exception e) {
-      LOGGER.warn("read auth info from dockerconfigjson failed.", e);
-    }
-  }
-
-
-  final class FileUpdateCheckThread implements Runnable {
-
-    private WatchService service;
-
-    private FileUpdateCheckThread(WatchService service) {
-      this.service = service;
-    }
-
-    public void run() {
-      while (true) {
-        try {
-          WatchKey watchKey = service.take();
-          // 清理掉已发生的事件,否则会导致事件遗留,进入死循环
-          watchKey.pollEvents();
-          synchronized (this) {
-            createAuthHeaders();
-          }
-          watchKey.reset();
-        } catch (InterruptedException e) {
-          LOGGER.error("error occured. detail : {}", e.getMessage());
-        }
-      }
-    }
-  }
-}
diff --git 
a/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/HttpTransportImplTest.java
 
b/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/HttpTransportImplTest.java
index 10dd094..1509574 100644
--- 
a/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/HttpTransportImplTest.java
+++ 
b/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/HttpTransportImplTest.java
@@ -29,7 +29,7 @@ import org.apache.http.StatusLine;
 import org.apache.http.client.HttpClient;
 import org.apache.http.entity.ContentType;
 import org.apache.http.entity.StringEntity;
-import 
org.apache.servicecomb.http.client.common.HttpConfiguration.AKSKProperties;
+import org.apache.servicecomb.http.client.auth.RequestAuthHeaderProvider;
 import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -39,9 +39,7 @@ public class HttpTransportImplTest {
   @Test
   public void TestHttpTransport() throws IOException {
     HttpClient httpClient = mock(HttpClient.class);
-    AKSKProperties akskProperties = new AKSKProperties();
-    akskProperties.setEnabled(false);
-
+    RequestAuthHeaderProvider requestAuthHeaderProvider = 
mock(RequestAuthHeaderProvider.class);
     org.apache.http.HttpResponse httpResponse = 
mock(org.apache.http.HttpResponse.class);
     StatusLine statusLine = mock(StatusLine.class);
     when(statusLine.getStatusCode()).thenReturn(200);
@@ -53,7 +51,7 @@ public class HttpTransportImplTest {
 
     when(httpClient.execute(Mockito.any())).thenReturn(httpResponse);
 
-    HttpTransportImpl httpTransport = new HttpTransportImpl(httpClient, 
akskProperties);
+    HttpTransportImpl httpTransport = new HttpTransportImpl(httpClient, 
requestAuthHeaderProvider);
     Map<String, String> extraHeaders = new HashMap<>();
     extraHeaders.put("test", "testContext");
     httpTransport.addHeaders(extraHeaders);
diff --git 
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/AddressManager.java
 
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/AddressManager.java
index 01f26f6..93b47ba 100644
--- 
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/AddressManager.java
+++ 
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/AddressManager.java
@@ -33,7 +33,7 @@ public class AddressManager {
   public AddressManager(String projectName, List<String> addresses) {
     this.projectName = projectName;
     this.addresses = new ArrayList<>(addresses.size());
-    addresses.forEach((address -> this.addresses.add(formatAddress(address))));
+    addresses.forEach((address -> this.addresses.add(address)));
     this.index = new Random().nextInt(addresses.size());
   }
 
@@ -57,6 +57,12 @@ public class AddressManager {
 
   public String address() {
     synchronized (this) {
+      return formatAddress(addresses.get(index));
+    }
+  }
+
+  public String nonFormattedAddress() {
+    synchronized (this) {
       return addresses.get(index);
     }
   }
diff --git 
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterClient.java
 
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterClient.java
index fdbd64a..1b2cd37 100755
--- 
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterClient.java
+++ 
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterClient.java
@@ -26,7 +26,7 @@ import java.util.Map;
 
 import org.apache.http.HttpStatus;
 import org.apache.http.client.utils.URIBuilder;
-import 
org.apache.servicecomb.http.client.common.HttpConfiguration.AKSKProperties;
+import org.apache.servicecomb.http.client.auth.RequestAuthHeaderProvider;
 import 
org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties;
 import org.apache.servicecomb.http.client.common.HttpResponse;
 import org.apache.servicecomb.http.client.common.HttpTransport;
@@ -48,6 +48,8 @@ import 
org.apache.servicecomb.service.center.client.model.MicroserviceInstancesR
 import org.apache.servicecomb.service.center.client.model.MicroserviceResponse;
 import 
org.apache.servicecomb.service.center.client.model.MicroservicesResponse;
 import org.apache.servicecomb.service.center.client.model.ModifySchemasRequest;
+import org.apache.servicecomb.service.center.client.model.RbacTokenRequest;
+import org.apache.servicecomb.service.center.client.model.RbacTokenResponse;
 import 
org.apache.servicecomb.service.center.client.model.RegisteredMicroserviceInstanceResponse;
 import 
org.apache.servicecomb.service.center.client.model.RegisteredMicroserviceResponse;
 import org.apache.servicecomb.service.center.client.model.SchemaInfo;
@@ -64,11 +66,12 @@ public class ServiceCenterClient implements 
ServiceCenterOperation {
     this.httpClient = httpClient;
   }
 
-  public ServiceCenterClient(AddressManager addressManager, SSLProperties 
sslProperties,
-      AKSKProperties akskProperties,
+  public ServiceCenterClient(AddressManager addressManager,
+      SSLProperties sslProperties,
+      RequestAuthHeaderProvider requestAuthHeaderProvider,
       String tenantName,
       Map<String, String> extraGlobalHeaders) {
-    HttpTransport httpTransport = 
HttpTransportFactory.createHttpTransport(sslProperties, akskProperties);
+    HttpTransport httpTransport = 
HttpTransportFactory.createHttpTransport(sslProperties, 
requestAuthHeaderProvider);
     httpTransport.addHeaders(extraGlobalHeaders);
 
     this.httpClient = new ServiceCenterRawClient.Builder()
@@ -488,4 +491,31 @@ public class ServiceCenterClient implements 
ServiceCenterOperation {
           "update service schema fails", e);
     }
   }
+
+  @Override
+  public RbacTokenResponse queryToken(RbacTokenRequest request) {
+    try {
+      HttpResponse response = httpClient
+          .postHttpRequestAbsoluteUrl("/v4/token", null,
+              HttpUtils.serialize(request));
+      if (response.getStatusCode() == HttpStatus.SC_OK) {
+        RbacTokenResponse result = 
HttpUtils.deserialize(response.getContent(), RbacTokenResponse.class);
+        result.setStatusCode(HttpStatus.SC_OK);
+        return result;
+      } else if (response.getStatusCode() == HttpStatus.SC_NOT_FOUND ||
+          response.getStatusCode() == HttpStatus.SC_FORBIDDEN) {
+        RbacTokenResponse result = new RbacTokenResponse();
+        result.setStatusCode(response.getStatusCode());
+        return result;
+      } else {
+        throw new OperationException(
+            "query token failed, statusCode = " + response.getStatusCode() + 
"; message = " + response
+                .getMessage()
+                + "; content = " + response.getContent());
+      }
+    } catch (IOException e) {
+      throw new OperationException(
+          "query token failed", e);
+    }
+  }
 }
diff --git 
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterOperation.java
 
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterOperation.java
index 1f0f4f7..41c2598 100644
--- 
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterOperation.java
+++ 
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterOperation.java
@@ -26,6 +26,8 @@ import 
org.apache.servicecomb.service.center.client.model.MicroserviceInstanceSt
 import 
org.apache.servicecomb.service.center.client.model.MicroserviceInstancesResponse;
 import 
org.apache.servicecomb.service.center.client.model.MicroservicesResponse;
 import org.apache.servicecomb.service.center.client.model.ModifySchemasRequest;
+import org.apache.servicecomb.service.center.client.model.RbacTokenRequest;
+import org.apache.servicecomb.service.center.client.model.RbacTokenResponse;
 import 
org.apache.servicecomb.service.center.client.model.RegisteredMicroserviceInstanceResponse;
 import 
org.apache.servicecomb.service.center.client.model.RegisteredMicroserviceResponse;
 import org.apache.servicecomb.service.center.client.model.SchemaInfo;
@@ -148,4 +150,12 @@ public interface ServiceCenterOperation {
    * @throws OperationException If some problems happened to contact service 
center or non http 200 returned.
    */
   boolean sendHeartBeat(String serviceId, String instanceId);
+
+  /**
+   * query token using user confidential
+   *
+   * @return if heartbeat is successful
+   * @throws OperationException If some problems happened to contact service 
center or non http 200 returned.
+   */
+  RbacTokenResponse queryToken(RbacTokenRequest request);
 }
diff --git 
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClient.java
 
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClient.java
index d7748ee..4bf1e3e 100755
--- 
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClient.java
+++ 
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClient.java
@@ -46,28 +46,35 @@ public class ServiceCenterRawClient {
   }
 
   public HttpResponse getHttpRequest(String url, Map<String, String> headers, 
String content) throws IOException {
-    return doHttpRequest(url, headers, content, HttpRequest.GET);
+    return doHttpRequest(url, false, headers, content, HttpRequest.GET);
+  }
+
+  public HttpResponse postHttpRequestAbsoluteUrl(String url, Map<String, 
String> headers, String content)
+      throws IOException {
+    return doHttpRequest(url, true, headers, content, HttpRequest.POST);
   }
 
   public HttpResponse postHttpRequest(String url, Map<String, String> headers, 
String content) throws IOException {
-    return doHttpRequest(url, headers, content, HttpRequest.POST);
+    return doHttpRequest(url, false, headers, content, HttpRequest.POST);
   }
 
   public HttpResponse putHttpRequest(String url, Map<String, String> headers, 
String content) throws IOException {
-    return doHttpRequest(url, headers, content, HttpRequest.PUT);
+    return doHttpRequest(url, false, headers, content, HttpRequest.PUT);
   }
 
   public HttpResponse deleteHttpRequest(String url, Map<String, String> 
headers, String content) throws IOException {
-    return doHttpRequest(url, headers, content, HttpRequest.DELETE);
+    return doHttpRequest(url, false, headers, content, HttpRequest.DELETE);
   }
 
-  private HttpResponse doHttpRequest(String url, Map<String, String> headers, 
String content, String method)
+  private HttpResponse doHttpRequest(String url, boolean absoluteUrl, 
Map<String, String> headers, String content,
+      String method)
       throws IOException {
     if (headers == null) {
       headers = new HashMap<>();
     }
     headers.put(HEADER_TENANT_NAME, tenantName);
-    HttpRequest httpRequest = new HttpRequest(addressManager.address() + url, 
headers, content, method);
+    String address = absoluteUrl ? addressManager.nonFormattedAddress() + url 
: addressManager.address() + url;
+    HttpRequest httpRequest = new HttpRequest(address, headers, content, 
method);
 
     try {
       return httpTransport.doRequest(httpRequest);
diff --git 
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/api/request/RbacTokenRequest.java
 
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/RbacTokenRequest.java
similarity index 76%
rename from 
service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/api/request/RbacTokenRequest.java
rename to 
clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/RbacTokenRequest.java
index fa6ee71..cd92636 100644
--- 
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/api/request/RbacTokenRequest.java
+++ 
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/RbacTokenRequest.java
@@ -15,22 +15,19 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.serviceregistry.api.request;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
+package org.apache.servicecomb.service.center.client.model;
 
 public class RbacTokenRequest {
-  @JsonProperty("name")
-  private String accountName;
+  private String name;
 
   private String password;
 
-  public String getAccountName() {
-    return accountName;
+  public String getName() {
+    return name;
   }
 
-  public void setAccountName(String accountName) {
-    this.accountName = accountName;
+  public void setName(String name) {
+    this.name = name;
   }
 
   public String getPassword() {
@@ -44,7 +41,7 @@ public class RbacTokenRequest {
   @Override
   public String toString() {
     final StringBuilder sb = new StringBuilder("RbacTokenRequest{");
-    sb.append("accountName='").append(accountName).append('\'');
+    sb.append("name='").append(name).append('\'');
     sb.append(", password='").append(password).append('\'');
     sb.append('}');
     return sb.toString();
diff --git 
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/api/response/RbacTokenResponse.java
 
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/RbacTokenResponse.java
similarity index 75%
rename from 
service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/api/response/RbacTokenResponse.java
rename to 
clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/RbacTokenResponse.java
index 40ecadc..fc6b77c 100644
--- 
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/api/response/RbacTokenResponse.java
+++ 
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/RbacTokenResponse.java
@@ -15,10 +15,10 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.serviceregistry.api.response;
+package org.apache.servicecomb.service.center.client.model;
 
 public class RbacTokenResponse {
-  private transient int statusCode;
+  private int statusCode;
 
   private String token;
 
@@ -37,13 +37,4 @@ public class RbacTokenResponse {
   public void setToken(String token) {
     this.token = token;
   }
-
-  @Override
-  public String toString() {
-    final StringBuilder sb = new StringBuilder("RbacTokenResponse{");
-    sb.append("statusCode=").append(statusCode);
-    sb.append(", token='").append(token).append('\'');
-    sb.append('}');
-    return sb.toString();
-  }
 }
diff --git 
a/core/src/main/java/org/apache/servicecomb/core/ConfigurationSpringInitializer.java
 
b/core/src/main/java/org/apache/servicecomb/core/ConfigurationSpringInitializer.java
index 85647d3..3aae470 100644
--- 
a/core/src/main/java/org/apache/servicecomb/core/ConfigurationSpringInitializer.java
+++ 
b/core/src/main/java/org/apache/servicecomb/core/ConfigurationSpringInitializer.java
@@ -26,7 +26,10 @@ import java.util.Properties;
 
 import org.apache.commons.configuration.AbstractConfiguration;
 import org.apache.servicecomb.config.ConfigUtil;
+import org.apache.servicecomb.config.YAMLUtil;
+import org.apache.servicecomb.config.archaius.sources.MicroserviceConfigLoader;
 import org.apache.servicecomb.config.spi.ConfigCenterConfigurationSource;
+import org.apache.servicecomb.foundation.bootstrap.BootStrapService;
 import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -41,8 +44,6 @@ import org.springframework.core.env.MapPropertySource;
 import org.springframework.core.env.PropertySource;
 import org.springframework.util.StringUtils;
 
-import com.google.common.collect.Lists;
-import com.netflix.config.ConcurrentCompositeConfiguration;
 import com.netflix.config.ConfigurationManager;
 import com.netflix.config.DynamicPropertyFactory;
 
@@ -66,6 +67,9 @@ public class ConfigurationSpringInitializer extends 
PropertyPlaceholderConfigure
 
   public static final String EXTRA_CONFIG_SOURCE_PREFIX = "extraConfig-";
 
+  private final List<BootStrapService> bootStrapServices =
+      SPIServiceUtils.getSortedService(BootStrapService.class);
+
   public ConfigurationSpringInitializer() {
     setOrder(Ordered.LOWEST_PRECEDENCE / 2);
     setIgnoreUnresolvablePlaceholders(true);
@@ -82,49 +86,81 @@ public class ConfigurationSpringInitializer extends 
PropertyPlaceholderConfigure
 
     Map<String, Object> extraConfig = getAllProperties(environment);
 
+    addMicroserviceYAMLToSpring(environment);
+
+    startupBootStrapService(environment);
+
     ConfigUtil.addExtraConfig(EXTRA_CONFIG_SOURCE_PREFIX + environmentName, 
extraConfig);
 
     ConfigUtil.installDynamicConfig();
 
-    setUpSpringPropertySource(environment);
+    addDynamicConfigurationToSpring(environment);
+  }
+
+  private void startupBootStrapService(Environment environment) {
+    bootStrapServices.forEach(bootStrapService -> 
bootStrapService.startup(environment));
   }
 
-  private void setUpSpringPropertySource(Environment environment) {
+  private void addMicroserviceYAMLToSpring(Environment environment) {
     if (environment instanceof ConfigurableEnvironment) {
       ConfigurableEnvironment ce = (ConfigurableEnvironment) environment;
-      ConfigCenterConfigurationSource configCenterConfigurationSource =
-          
SPIServiceUtils.getTargetService(ConfigCenterConfigurationSource.class);
-      if (configCenterConfigurationSource != null) {
-        try {
-          ce.getPropertySources()
-              .addFirst(new MapPropertySource("dynamic-source", 
configCenterConfigurationSource.getCurrentData()));
-        } catch (Exception e) {
-          LOGGER.warn("set up spring property source failed. msg: {}", 
e.getMessage());
-        }
-      }
-      ConcurrentCompositeConfiguration concurrentCompositeConfiguration = 
ConfigUtil.createLocalConfig();
-      ce.getPropertySources().addLast(
-          new 
EnumerablePropertySource<ConcurrentCompositeConfiguration>("microservice.yaml",
-              concurrentCompositeConfiguration) {
+      MicroserviceConfigLoader loader = new MicroserviceConfigLoader();
+      loader.loadAndSort();
+
+      ce.getPropertySources()
+          .addLast(new 
EnumerablePropertySource<MicroserviceConfigLoader>("microservice.yaml",
+              loader) {
+
+            private boolean parsed = false;
+
+            private Map<String, Object> values = null;
+
             private String[] propertyNames = null;
 
             @Override
             public String[] getPropertyNames() {
-              if (propertyNames == null) {
-                List<String> keyList = 
Lists.newArrayList(this.source.getKeys());
-                propertyNames = keyList.toArray(new String[keyList.size()]);
+              if (!parsed) {
+                parseData();
               }
+
               return propertyNames;
             }
 
             @Override
             public Object getProperty(String s) {
-              return this.source.getProperty(s);
+              if (!parsed) {
+                parseData();
+              }
+
+              return this.values.get(s);
+            }
+
+            private void parseData() {
+              values = new HashMap<>();
+              loader.getConfigModels()
+                  .forEach(configModel -> 
values.putAll(YAMLUtil.retrieveItems("", configModel.getConfig())));
+              propertyNames = values.keySet().toArray(new 
String[values.size()]);
             }
           });
     }
   }
 
+  private void addDynamicConfigurationToSpring(Environment environment) {
+    if (environment instanceof ConfigurableEnvironment) {
+      ConfigurableEnvironment ce = (ConfigurableEnvironment) environment;
+      ConfigCenterConfigurationSource configCenterConfigurationSource =
+          
SPIServiceUtils.getTargetService(ConfigCenterConfigurationSource.class);
+      if (configCenterConfigurationSource != null) {
+        try {
+          ce.getPropertySources()
+              .addFirst(new MapPropertySource("dynamic-source", 
configCenterConfigurationSource.getCurrentData()));
+        } catch (Exception e) {
+          LOGGER.warn("set up spring property source failed. msg: {}", 
e.getMessage());
+        }
+      }
+    }
+  }
+
   @Override
   protected Properties mergeProperties() throws IOException {
     Properties properties = super.mergeProperties();
diff --git a/coverage-reports/pom.xml b/coverage-reports/pom.xml
index 1327d6e..e2a5763 100644
--- a/coverage-reports/pom.xml
+++ b/coverage-reports/pom.xml
@@ -136,6 +136,10 @@
     </dependency>
     <dependency>
       <groupId>org.apache.servicecomb</groupId>
+      <artifactId>foundation-spi</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.servicecomb</groupId>
       <artifactId>foundation-ssl</artifactId>
     </dependency>
     <dependency>
diff --git 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIOrder.java
 
b/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/IConfigurationEndpoint.java
similarity index 84%
copy from 
foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIOrder.java
copy to 
demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/IConfigurationEndpoint.java
index b9fc016..dc72a9f 100644
--- 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIOrder.java
+++ 
b/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/IConfigurationEndpoint.java
@@ -15,10 +15,8 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.foundation.common.utils;
+package org.apache.servicecomb.demo.multiServiceCenterClient;
 
-public interface SPIOrder {
-  default int getOrder() {
-    return 0;
-  }
+public interface IConfigurationEndpoint {
+  String getValue(String key, int type);
 }
diff --git 
a/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/RegistryClientTest.java
 
b/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/RegistryClientTest.java
index f8f24a1..85a6296 100644
--- 
a/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/RegistryClientTest.java
+++ 
b/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/RegistryClientTest.java
@@ -26,7 +26,7 @@ import java.util.concurrent.TimeUnit;
 import org.apache.servicecomb.demo.CategorizedTestCase;
 import org.apache.servicecomb.demo.TestMgr;
 import org.apache.servicecomb.foundation.common.event.SimpleEventBus;
-import 
org.apache.servicecomb.http.client.common.HttpConfiguration.AKSKProperties;
+import 
org.apache.servicecomb.http.client.auth.DefaultRequestAuthHeaderProvider;
 import 
org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties;
 import org.apache.servicecomb.service.center.client.AddressManager;
 import 
org.apache.servicecomb.service.center.client.DiscoveryEvents.InstanceChangedEvent;
@@ -66,10 +66,8 @@ public class RegistryClientTest implements 
CategorizedTestCase {
     AddressManager addressManager = new AddressManager("default", 
Arrays.asList("http://127.0.0.1:30100";));
     SSLProperties sslProperties = new SSLProperties();
     sslProperties.setEnabled(false);
-    AKSKProperties akskProperties = new AKSKProperties();
-    akskProperties.setEnabled(false);
-    ServiceCenterClient serviceCenterClient = new 
ServiceCenterClient(addressManager, sslProperties, akskProperties,
-        "default", null);
+    ServiceCenterClient serviceCenterClient = new 
ServiceCenterClient(addressManager, sslProperties,
+        new DefaultRequestAuthHeaderProvider(), "default", null);
     EventBus eventBus = new SimpleEventBus();
     ServiceCenterRegistration serviceCenterRegistration = new 
ServiceCenterRegistration(serviceCenterClient, eventBus);
     Microservice microservice = new Microservice();
diff --git 
a/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/ServerBTest.java
 
b/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/ServerBTest.java
index 4aa9dc2..3a1abd1 100644
--- 
a/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/ServerBTest.java
+++ 
b/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/ServerBTest.java
@@ -27,9 +27,25 @@ public class ServerBTest implements CategorizedTestCase {
   @RpcReference(microserviceName = "demo-multi-service-center-serverB", 
schemaId = "ServerEndpoint")
   private IServerEndpoint serverEndpoint;
 
+  @RpcReference(microserviceName = "demo-multi-service-center-serverB", 
schemaId = "ConfigurationEndpoint")
+  private IConfigurationEndpoint configurationEndpoint;
+
   @Override
   public void testRestTransport() throws Exception {
     TestMgr.check("hello", serverEndpoint.getName("hello"));
+
+    TestMgr.check("key1-boot", 
configurationEndpoint.getValue("demo.multi.service.center.serverB.key1", 1));
+    TestMgr.check("key1-boot", 
configurationEndpoint.getValue("demo.multi.service.center.serverB.key1", 2));
+    TestMgr.check("key1-boot", 
configurationEndpoint.getValue("demo.multi.service.center.serverB.key1", 3));
+    TestMgr.check("key2-override", 
configurationEndpoint.getValue("demo.multi.service.center.serverB.key2", 1));
+    TestMgr.check("key2-override", 
configurationEndpoint.getValue("demo.multi.service.center.serverB.key2", 2));
+    TestMgr.check("key2-override", 
configurationEndpoint.getValue("demo.multi.service.center.serverB.key2", 3));
+    TestMgr.check("key3", 
configurationEndpoint.getValue("demo.multi.service.center.serverB.key3", 1));
+    TestMgr.check("key3", 
configurationEndpoint.getValue("demo.multi.service.center.serverB.key3", 2));
+    TestMgr.check("key3", 
configurationEndpoint.getValue("demo.multi.service.center.serverB.key3", 3));
+    TestMgr.check("key4-boot", 
configurationEndpoint.getValue("demo.multi.service.center.serverB.key4", 1));
+    TestMgr.check("key4-boot", 
configurationEndpoint.getValue("demo.multi.service.center.serverB.key4", 2));
+    TestMgr.check("key4-boot", 
configurationEndpoint.getValue("demo.multi.service.center.serverB.key4", 3));
   }
 
   @Override
diff --git 
a/demo/demo-multi-service-center/demo-multi-service-center-serverB/src/main/java/org/apache/servicecomb/demo/multiServiceCenterServerB/ConfigurationEndpoint.java
 
b/demo/demo-multi-service-center/demo-multi-service-center-serverB/src/main/java/org/apache/servicecomb/demo/multiServiceCenterServerB/ConfigurationEndpoint.java
new file mode 100644
index 0000000..9c4c2b5
--- /dev/null
+++ 
b/demo/demo-multi-service-center/demo-multi-service-center-serverB/src/main/java/org/apache/servicecomb/demo/multiServiceCenterServerB/ConfigurationEndpoint.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.servicecomb.demo.multiServiceCenterServerB;
+
+import javax.ws.rs.core.MediaType;
+
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.env.Environment;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import com.netflix.config.DynamicPropertyFactory;
+
+@RestSchema(schemaId = "ConfigurationEndpoint")
+@RequestMapping(path = "/register/url/config", produces = 
MediaType.APPLICATION_JSON)
+public class ConfigurationEndpoint {
+  private static final Logger LOGGER
+      = LoggerFactory.getLogger(ServerEndpoint.class);
+
+  @Autowired
+  private Environment environment;
+
+  @Value("${demo.multi.service.center.serverB.key1}")
+  private String key1;
+
+  @Value("${demo.multi.service.center.serverB.key2}")
+  private String key2;
+
+  @Value("${demo.multi.service.center.serverB.key3}")
+  private String key3;
+
+  @Value("${demo.multi.service.center.serverB.key4}")
+  private String key4;
+
+  @GetMapping(path = "/config")
+  public String getValue(@RequestParam(name = "key") String key, 
@RequestParam(name = "type") int type) {
+    if (type == 1) {
+      return environment.getProperty(key);
+    } else if (type == 2) {
+      return DynamicPropertyFactory.getInstance().getStringProperty(key, 
null).get();
+    } else {
+      switch (key) {
+        case "demo.multi.service.center.serverB.key1":
+          return key1;
+        case "demo.multi.service.center.serverB.key2":
+          return key2;
+        case "demo.multi.service.center.serverB.key3":
+          return key3;
+        case "demo.multi.service.center.serverB.key4":
+          return key4;
+        default:
+          return null;
+      }
+    }
+  }
+}
diff --git 
a/demo/demo-multi-service-center/demo-multi-service-center-serverB/src/main/resources/application.yml
 
b/demo/demo-multi-service-center/demo-multi-service-center-serverB/src/main/resources/application.yml
index 834ca56..663c6ad 100644
--- 
a/demo/demo-multi-service-center/demo-multi-service-center-serverB/src/main/resources/application.yml
+++ 
b/demo/demo-multi-service-center/demo-multi-service-center-serverB/src/main/resources/application.yml
@@ -29,4 +29,9 @@ servicecomb:
     registry:
       address: http://127.0.0.1:40100
   rest:
-    address: 0.0.0.0:8082
\ No newline at end of file
+    address: 0.0.0.0:8082
+
+demo.multi.service.center.serverB:
+  key1: key1-boot
+  key4: key4-boot
+
diff --git a/demo/demo-schema/src/main/resources/microservice.yaml 
b/demo/demo-multi-service-center/demo-multi-service-center-serverB/src/main/resources/microservice.yaml
similarity index 90%
copy from demo/demo-schema/src/main/resources/microservice.yaml
copy to 
demo/demo-multi-service-center/demo-multi-service-center-serverB/src/main/resources/microservice.yaml
index d26c026..34d28d2 100644
--- a/demo/demo-schema/src/main/resources/microservice.yaml
+++ 
b/demo/demo-multi-service-center/demo-multi-service-center-serverB/src/main/resources/microservice.yaml
@@ -14,12 +14,9 @@
 ## See the License for the specific language governing permissions and
 ## limitations under the License.
 ## ---------------------------------------------------------------------------
-servicecomb-config-order: -1
 
-cse:
-  test:
-    duplicate1: older
+servicecomb-config-order: 1
 
-servicecomb:
-  test:
-    duplicate2: older
\ No newline at end of file
+demo.multi.service.center.serverB:
+  key1: key1-override
+  key2: key2-override
\ No newline at end of file
diff --git 
a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/TestMgr.java 
b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/TestMgr.java
index f2218bc..ede3da4 100644
--- a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/TestMgr.java
+++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/TestMgr.java
@@ -19,6 +19,7 @@ package org.apache.servicecomb.demo;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -31,6 +32,8 @@ public class TestMgr {
 
   private static String msg = "";
 
+  private static AtomicLong checkes = new AtomicLong(0);
+
   public static void setMsg(String msg) {
     TestMgr.msg = msg;
   }
@@ -44,6 +47,8 @@ public class TestMgr {
   }
 
   public static void check(Object expect, Object real, Throwable error) {
+    checkes.incrementAndGet();
+
     if (expect == real) {
       return;
     }
@@ -61,12 +66,16 @@ public class TestMgr {
   }
 
   public static void checkNotEmpty(String real) {
+    checkes.incrementAndGet();
+
     if (StringUtils.isEmpty(real)) {
       errorList.add(new Error(msg + " | unexpected null result, method is " + 
getCaller()));
     }
   }
 
   public static void failed(String desc, Throwable e) {
+    checkes.incrementAndGet();
+
     Error error = new Error(msg + " | " + desc + ", method is " + getCaller());
     if (e != null) {
       error.setStackTrace(error.getStackTrace());
@@ -81,10 +90,14 @@ public class TestMgr {
   public static void summary() {
     if (errorList.isEmpty()) {
       LOGGER.info("............. test finished ............");
+      LOGGER.info("............. total checks : " + checkes.get());
       return;
     }
 
     LOGGER.info("............. test not finished ............");
+    LOGGER.info("............. total checks : " + checkes.get());
+    LOGGER.info("............. total errors : " + errorList.size());
+    LOGGER.info("............. error details: ");
     for (Throwable e : errorList) {
       LOGGER.info("", e);
     }
diff --git a/demo/demo-schema/src/main/resources/microservice.yaml 
b/demo/demo-schema/src/main/resources/microservice.yaml
index d26c026..97db791 100644
--- a/demo/demo-schema/src/main/resources/microservice.yaml
+++ b/demo/demo-schema/src/main/resources/microservice.yaml
@@ -22,4 +22,9 @@ cse:
 
 servicecomb:
   test:
-    duplicate2: older
\ No newline at end of file
+    duplicate2: older
+
+demo.multi.service.center.serverB:
+  key1: key1
+  key2: key2
+  key3: key3
\ No newline at end of file
diff --git a/dependencies/bom/pom.xml b/dependencies/bom/pom.xml
index 81ba80f..addebe8 100644
--- a/dependencies/bom/pom.xml
+++ b/dependencies/bom/pom.xml
@@ -160,6 +160,11 @@
       </dependency>
       <dependency>
         <groupId>org.apache.servicecomb</groupId>
+        <artifactId>foundation-spi</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.servicecomb</groupId>
         <artifactId>foundation-ssl</artifactId>
         <version>${project.version}</version>
       </dependency>
diff --git a/distribution/pom.xml b/distribution/pom.xml
index 7c6d0f7..fa9d9a2 100644
--- a/distribution/pom.xml
+++ b/distribution/pom.xml
@@ -134,6 +134,10 @@
     </dependency>
     <dependency>
       <groupId>org.apache.servicecomb</groupId>
+      <artifactId>foundation-spi</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.servicecomb</groupId>
       <artifactId>foundation-ssl</artifactId>
     </dependency>
     <dependency>
diff --git 
a/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/client/ConfigCenterClient.java
 
b/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/client/ConfigCenterClient.java
index 622c6c2..bdf02a2 100644
--- 
a/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/client/ConfigCenterClient.java
+++ 
b/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/client/ConfigCenterClient.java
@@ -38,13 +38,12 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.commons.lang.StringUtils;
 import 
org.apache.servicecomb.config.archaius.sources.ConfigCenterConfigurationSourceImpl;
-import org.apache.servicecomb.foundation.auth.AuthHeaderProvider;
+import org.apache.servicecomb.foundation.auth.AuthHeaderLoader;
 import org.apache.servicecomb.foundation.auth.SignRequest;
 import org.apache.servicecomb.foundation.common.event.EventManager;
 import org.apache.servicecomb.foundation.common.net.IpPort;
 import org.apache.servicecomb.foundation.common.net.NetUtils;
 import org.apache.servicecomb.foundation.common.utils.JsonUtils;
-import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
 import 
org.apache.servicecomb.foundation.vertx.client.http.HttpClientWithContext;
 import org.apache.servicecomb.foundation.vertx.client.http.HttpClients;
 import org.slf4j.Logger;
@@ -95,9 +94,6 @@ public class ConfigCenterClient {
 
   private boolean isWatching = false;
 
-  private final List<AuthHeaderProvider> authHeaderProviders =
-      SPIServiceUtils.getSortedService(AuthHeaderProvider.class);
-
   private URIConst uriConst = new URIConst();
 
   public ConfigCenterClient(ConfigCenterConfigurationSourceImpl.UpdateHandler 
updateHandler) {
@@ -153,8 +149,8 @@ public class ConfigCenterClient {
         if (ConfigCenterConfig.INSTANCE.getToken() != null) {
           request.headers().add("X-Auth-Token", 
ConfigCenterConfig.INSTANCE.getToken());
         }
-        authHeaderProviders.forEach(provider -> request.headers()
-            .addAll(provider.getSignAuthHeaders(signReq)));
+        request.headers()
+            .addAll(AuthHeaderLoader.getInstance().loadAuthHeaders(signReq));
         request.exceptionHandler(e -> {
           LOGGER.error("Fetch member from {} failed. Error message is [{}].", 
configCenter, e.getMessage());
           logIfDnsFailed(e);
@@ -216,7 +212,7 @@ public class ConfigCenterClient {
 
       vertxHttpClient.runOnContext(client -> {
         Map<String, String> authHeaders = new HashMap<>();
-        authHeaderProviders.forEach(provider -> 
authHeaders.putAll(provider.getSignAuthHeaders(
+        authHeaders.putAll(AuthHeaderLoader.getInstance().loadAuthHeaders((
             createSignRequest(null, configCenter + url, headers, null))));
         WebSocketConnectOptions options = new WebSocketConnectOptions();
         options.setHost(ipPort.getHostOrIp()).setPort(refreshPort).setURI(url)
@@ -354,11 +350,11 @@ public class ConfigCenterClient {
         }
         headers.put("x-environment", environment);
         request.headers().addAll(headers);
-        authHeaderProviders.forEach(provider -> request.headers()
-            
.addAll(provider.getSignAuthHeaders(createSignRequest(request.method().toString(),
+        request.headers()
+            
.addAll(AuthHeaderLoader.getInstance().loadAuthHeaders(createSignRequest(request.method().toString(),
                 configcenter + path,
                 headers,
-                null))));
+                null)));
         request.exceptionHandler(e -> {
           EventManager.post(new ConnFailEvent("fetch config fail"));
           LOGGER.error("Config update from {} failed. Error message is [{}].",
diff --git a/foundations/foundation-common/pom.xml 
b/foundations/foundation-common/pom.xml
index 5b2fa35..f8fa378 100644
--- a/foundations/foundation-common/pom.xml
+++ b/foundations/foundation-common/pom.xml
@@ -84,6 +84,11 @@
 
     <dependency>
       <groupId>org.apache.servicecomb</groupId>
+      <artifactId>foundation-spi</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.servicecomb</groupId>
       <artifactId>foundation-test-scaffolding</artifactId>
     </dependency>
     <dependency>
diff --git 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/DefaultCipher.java
 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/DefaultCipher.java
index 7138cca..62cb24d 100644
--- 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/DefaultCipher.java
+++ 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/DefaultCipher.java
@@ -18,7 +18,7 @@
 package org.apache.servicecomb.foundation.auth;
 
 public final class DefaultCipher implements Cipher {
-  public static final String DEFAULT_CYPHER = "default";
+  public static final String CIPHER_NAME = "default";
 
   private static final DefaultCipher INSTANCE = new DefaultCipher();
 
@@ -31,7 +31,7 @@ public final class DefaultCipher implements Cipher {
 
   @Override
   public String name() {
-    return DEFAULT_CYPHER;
+    return CIPHER_NAME;
   }
 
   @Override
diff --git 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderProvider.java
 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/ShaAKSKCipher.java
similarity index 76%
copy from 
foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderProvider.java
copy to 
foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/ShaAKSKCipher.java
index 313c19e..ee857e6 100644
--- 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderProvider.java
+++ 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/ShaAKSKCipher.java
@@ -17,15 +17,16 @@
 
 package org.apache.servicecomb.foundation.auth;
 
-import java.util.HashMap;
-import java.util.Map;
+public class ShaAKSKCipher implements Cipher {
+  public static final String CIPHER_NAME = "ShaAKSKCipher";
 
-public interface AuthHeaderProvider {
-  default Map<String, String> authHeaders() {
-    return new HashMap<>(0);
+  @Override
+  public String name() {
+    return CIPHER_NAME;
   }
 
-  default Map<String, String> getSignAuthHeaders(SignRequest request) {
-    return authHeaders();
+  @Override
+  public char[] decrypt(char[] encrypted) {
+    return encrypted;
   }
 }
diff --git a/foundations/pom.xml b/foundations/foundation-spi/pom.xml
similarity index 67%
copy from foundations/pom.xml
copy to foundations/foundation-spi/pom.xml
index f1b0131..15ef02f 100644
--- a/foundations/pom.xml
+++ b/foundations/foundation-spi/pom.xml
@@ -20,21 +20,20 @@
   <modelVersion>4.0.0</modelVersion>
   <parent>
     <groupId>org.apache.servicecomb</groupId>
-    <artifactId>java-chassis-parent</artifactId>
+    <artifactId>foundations</artifactId>
     <version>2.1.3-SNAPSHOT</version>
-    <relativePath>../parents/default</relativePath>
   </parent>
-  <artifactId>foundations</artifactId>
-  <name>Java Chassis::Foundations</name>
-  <packaging>pom</packaging>
-  <modules>
-    <module>foundation-vertx</module>
-    <module>foundation-common</module>
-    <module>foundation-config</module>
-    <module>foundation-metrics</module>
-    <module>foundation-ssl</module>
-    <module>foundation-test-scaffolding</module>
-    <module>foundation-protobuf</module>
-    <module>foundation-registry</module>
-  </modules>
+  <artifactId>foundation-spi</artifactId>
+  <name>Java Chassis::Foundations::SSL</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-core</artifactId>
+    </dependency>
+  </dependencies>
 </project>
diff --git 
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/AKSKHeaderExtensionUtil.java
 
b/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderLoader.java
similarity index 53%
rename from 
clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/AKSKHeaderExtensionUtil.java
rename to 
foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderLoader.java
index 7b97ed5..39e0bfa 100644
--- 
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/auth/AKSKHeaderExtensionUtil.java
+++ 
b/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderLoader.java
@@ -15,22 +15,27 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.http.client.common.auth;
+package org.apache.servicecomb.foundation.auth;
 
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
-public class AKSKHeaderExtensionUtil {
+import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
 
-  private static AKSKHeaderExtension headerExtension = new 
FileSystemMountAKSKHeaderExtension();
+public class AuthHeaderLoader {
+  private final List<AuthHeaderProvider> authHeaderProviders =
+      SPIServiceUtils.getSortedService(AuthHeaderProvider.class);
 
-  public static Map<String, String> genAuthHeaders() {
-    if (Files.exists(Paths.get(AKSKHeaderExtension.DEFAULT_SECRET_AUTH_PATH,
-        AKSKHeaderExtension.DEFAULT_SECRET_AUTH_NAME))) {
-      return headerExtension.getHeaders();
-    }
-    return Collections.emptyMap();
+  private static final AuthHeaderLoader INSTANCE = new AuthHeaderLoader();
+
+  public static AuthHeaderLoader getInstance() {
+    return INSTANCE;
+  }
+
+  public Map<String, String> loadAuthHeaders(SignRequest signRequest) {
+    Map<String, String> result = new HashMap<>();
+    authHeaderProviders.forEach(provider -> 
result.putAll(provider.getSignAuthHeaders(signRequest)));
+    return result;
   }
 }
diff --git 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderProvider.java
 
b/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderProvider.java
similarity index 100%
rename from 
foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderProvider.java
rename to 
foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderProvider.java
diff --git 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/SignRequest.java
 
b/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/auth/SignRequest.java
similarity index 100%
rename from 
foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/SignRequest.java
rename to 
foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/auth/SignRequest.java
diff --git 
a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef.java
 
b/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/bootstrap/BootStrapService.java
similarity index 60%
copy from 
foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef.java
copy to 
foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/bootstrap/BootStrapService.java
index 75f726e..9d04e2a 100644
--- 
a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef.java
+++ 
b/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/bootstrap/BootStrapService.java
@@ -15,8 +15,19 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.foundation.common.utils;
+package org.apache.servicecomb.foundation.bootstrap;
 
-public interface SPIServiceDef {
+import org.springframework.core.env.Environment;
 
+/**
+ * A boot strap service is loaded after Spring Environment is created.
+ *
+ * In boot strap service, user's can only read configurations from 
Environment. Dynamic configurations
+ *
+ * from config center is not available.
+ *
+ * e.g. an authentication service must be connected before connecting to 
config center, service center, etc.
+ */
+public interface BootStrapService {
+  void startup(Environment environment);
 }
diff --git 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIEnabled.java
 
b/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIEnabled.java
similarity index 100%
rename from 
foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIEnabled.java
rename to 
foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIEnabled.java
diff --git 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIOrder.java
 
b/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIOrder.java
similarity index 100%
rename from 
foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIOrder.java
rename to 
foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIOrder.java
diff --git 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIServiceUtils.java
 
b/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIServiceUtils.java
similarity index 100%
rename from 
foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIServiceUtils.java
rename to 
foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIServiceUtils.java
diff --git 
a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef.java
 
b/foundations/foundation-spi/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef.java
similarity index 100%
rename from 
foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef.java
rename to 
foundations/foundation-spi/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef.java
diff --git 
a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef0.java
 
b/foundations/foundation-spi/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef0.java
similarity index 100%
rename from 
foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef0.java
rename to 
foundations/foundation-spi/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef0.java
diff --git 
a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef0Impl.java
 
b/foundations/foundation-spi/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef0Impl.java
similarity index 100%
rename from 
foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef0Impl.java
rename to 
foundations/foundation-spi/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef0Impl.java
diff --git 
a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDefImpl.java
 
b/foundations/foundation-spi/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDefImpl.java
similarity index 100%
rename from 
foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDefImpl.java
rename to 
foundations/foundation-spi/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDefImpl.java
diff --git 
a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestSPIServiceUtils.java
 
b/foundations/foundation-spi/src/test/java/org/apache/servicecomb/foundation/common/utils/TestSPIServiceUtils.java
similarity index 100%
rename from 
foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestSPIServiceUtils.java
rename to 
foundations/foundation-spi/src/test/java/org/apache/servicecomb/foundation/common/utils/TestSPIServiceUtils.java
diff --git 
a/foundations/foundation-common/src/test/resources/META-INF/services/org.apache.servicecomb.foundation.common.utils.SPIServiceDef
 
b/foundations/foundation-spi/src/test/resources/META-INF/services/org.apache.servicecomb.foundation.common.utils.SPIServiceDef
similarity index 100%
copy from 
foundations/foundation-common/src/test/resources/META-INF/services/org.apache.servicecomb.foundation.common.utils.SPIServiceDef
copy to 
foundations/foundation-spi/src/test/resources/META-INF/services/org.apache.servicecomb.foundation.common.utils.SPIServiceDef
diff --git 
a/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLOption.java
 
b/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLOption.java
index b7b5034..2ac537e 100644
--- 
a/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLOption.java
+++ 
b/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLOption.java
@@ -36,7 +36,7 @@ import com.netflix.config.DynamicPropertyFactory;
  *
  */
 public final class SSLOption {
-  private static final SSLOption DEFAULT_OPTION = new SSLOption();
+  public static final SSLOption DEFAULT_OPTION = new SSLOption();
 
   public static final String DEFAULT_CIPHERS = 
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,"
       + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
diff --git a/foundations/pom.xml b/foundations/pom.xml
index f1b0131..1d88c46 100644
--- a/foundations/pom.xml
+++ b/foundations/pom.xml
@@ -28,6 +28,7 @@
   <name>Java Chassis::Foundations</name>
   <packaging>pom</packaging>
   <modules>
+    <module>foundation-spi</module>
     <module>foundation-vertx</module>
     <module>foundation-common</module>
     <module>foundation-config</module>
diff --git 
a/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/AKSKAuthHeaderProvider.java
 
b/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/AKSKAuthHeaderProvider.java
new file mode 100644
index 0000000..06eb7b1
--- /dev/null
+++ 
b/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/AKSKAuthHeaderProvider.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.servicecomb.huaweicloud.servicestage;
+
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.servicecomb.config.ConfigUtil;
+import org.apache.servicecomb.foundation.auth.AuthHeaderProvider;
+import org.apache.servicecomb.foundation.auth.Cipher;
+import org.apache.servicecomb.foundation.auth.DefaultCipher;
+import org.apache.servicecomb.foundation.auth.ShaAKSKCipher;
+import org.apache.servicecomb.foundation.common.utils.BeanUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AKSKAuthHeaderProvider implements AuthHeaderProvider {
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(AKSKAuthHeaderProvider.class);
+
+  private static final String CONFIG_AKSK_ENABLED = 
"servicecomb.credentials.akskEnabled";
+
+  private static final String CONFIG_ACCESS_KEY = 
"servicecomb.credentials.accessKey";
+
+  private static final String CONFIG_SECRET_KEY = 
"servicecomb.credentials.secretKey";
+
+  private static final String CONFIG_CIPHER = 
"servicecomb.credentials.akskCustomCipher";
+
+  private static final String CONFIG_PROJECT = 
"servicecomb.credentials.project";
+
+  private static final String VALUE_DEFAULT_PROJECT = "default";
+
+  private static final String VALUE_DEFAULT_CIPHER = "default";
+
+  private static final String X_SERVICE_AK = "X-Service-AK";
+
+  private static final String X_SERVICE_SHAAKSK = "X-Service-ShaAKSK";
+
+  private static final String X_SERVICE_PROJECT = "X-Service-Project";
+
+  private Map<String, String> headers = new HashMap<>();
+
+  private Configuration configuration = ConfigUtil.createLocalConfig();
+
+  private boolean enabled = configuration.getBoolean(CONFIG_AKSK_ENABLED, 
true);
+
+  private boolean loaded = false;
+
+  public Map<String, String> authHeaders() {
+    if (!enabled) {
+      return headers;
+    }
+
+    if (StringUtils.isEmpty(getAccessKey())) {
+      LOGGER.warn("ak sk auth enabled but access key is not configured, 
disable it at runtime. "
+              + "Config [{}] to false to disable it implicitly.",
+          CONFIG_AKSK_ENABLED);
+      enabled = false;
+      return headers;
+    }
+
+    if (!loaded) {
+      load();
+    }
+    return headers;
+  }
+
+  private synchronized void load() {
+    if (!loaded) {
+      headers.put(X_SERVICE_AK, getAccessKey());
+      headers.put(X_SERVICE_SHAAKSK, getSecretKey());
+      headers.put(X_SERVICE_PROJECT, getProject());
+    }
+  }
+
+  private String getAccessKey() {
+    return configuration.getString(CONFIG_ACCESS_KEY, "");
+  }
+
+  private String getCipher() {
+    return configuration.getString(CONFIG_CIPHER, VALUE_DEFAULT_CIPHER);
+  }
+
+  private String getSecretKey() {
+    String secretKey = configuration.getString(CONFIG_SECRET_KEY, "");
+    String decodedSecretKey = new 
String(findCipher().decrypt(secretKey.toCharArray()));
+
+    // ShaAKSKCipher 不解密, 认证的时候不处理;其他算法解密为 plain,需要 encode 为 ShaAKSKCipher 去认证。
+    if (ShaAKSKCipher.CIPHER_NAME.equalsIgnoreCase(getCipher())) {
+      return decodedSecretKey;
+    } else {
+      return sha256Encode(decodedSecretKey, getAccessKey());
+    }
+  }
+
+  private String getProject() {
+    return configuration.getString(CONFIG_PROJECT, VALUE_DEFAULT_PROJECT);
+  }
+
+  private Cipher findCipher() {
+    if (DefaultCipher.CIPHER_NAME.equals(getCipher())) {
+      return DefaultCipher.getInstance();
+    }
+
+    Map<String, Cipher> cipherBeans = BeanUtils.getBeansOfType(Cipher.class);
+    return cipherBeans.values().stream().filter(c -> 
c.name().equals(getCipher())).findFirst()
+        .orElseThrow(() -> new IllegalArgumentException("failed to find cipher 
named " + getCipher()));
+  }
+
+  public static String sha256Encode(String key, String data) {
+    try {
+      Mac sha256HMAC = Mac.getInstance("HmacSHA256");
+      SecretKeySpec secretKey = new 
SecretKeySpec(key.getBytes(StandardCharsets.UTF_8),
+          "HmacSHA256");
+      sha256HMAC.init(secretKey);
+      return 
Hex.encodeHexString(sha256HMAC.doFinal(data.getBytes(StandardCharsets.UTF_8)));
+    } catch (Exception e) {
+      throw new IllegalArgumentException("Can not encode ak sk. Please check 
the value is correct.", e);
+    }
+  }
+}
diff --git 
a/foundations/foundation-common/src/test/resources/META-INF/services/org.apache.servicecomb.foundation.common.utils.SPIServiceDef
 
b/huawei-cloud/servicestage/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.auth.AuthHeaderProvider
similarity index 91%
copy from 
foundations/foundation-common/src/test/resources/META-INF/services/org.apache.servicecomb.foundation.common.utils.SPIServiceDef
copy to 
huawei-cloud/servicestage/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.auth.AuthHeaderProvider
index eebf462..e756f89 100644
--- 
a/foundations/foundation-common/src/test/resources/META-INF/services/org.apache.servicecomb.foundation.common.utils.SPIServiceDef
+++ 
b/huawei-cloud/servicestage/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.auth.AuthHeaderProvider
@@ -15,4 +15,4 @@
 # limitations under the License.
 #
 
-org.apache.servicecomb.foundation.common.utils.SPIServiceDefImpl
\ No newline at end of file
+org.apache.servicecomb.huaweicloud.servicestage.AKSKAuthHeaderProvider
diff --git a/service-registry/registry-service-center/pom.xml 
b/service-registry/registry-service-center/pom.xml
index 0558158..8ecd320 100644
--- a/service-registry/registry-service-center/pom.xml
+++ b/service-registry/registry-service-center/pom.xml
@@ -56,6 +56,11 @@
     </dependency>
 
     <dependency>
+      <groupId>org.apache.servicecomb</groupId>
+      <artifactId>service-center-client</artifactId>
+    </dependency>
+
+    <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-lang3</artifactId>
     </dependency>
diff --git 
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/RBACBootStrapService.java
 
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/RBACBootStrapService.java
new file mode 100644
index 0000000..6b05677
--- /dev/null
+++ 
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/RBACBootStrapService.java
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.servicecomb.serviceregistry.auth;
+
+import static org.apache.servicecomb.foundation.ssl.SSLOption.DEFAULT_OPTION;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.servicecomb.foundation.auth.Cipher;
+import org.apache.servicecomb.foundation.auth.DefaultCipher;
+import org.apache.servicecomb.foundation.bootstrap.BootStrapService;
+import org.apache.servicecomb.foundation.common.utils.BeanUtils;
+import org.apache.servicecomb.foundation.ssl.SSLCustom;
+import org.apache.servicecomb.foundation.ssl.SSLOption;
+import 
org.apache.servicecomb.http.client.auth.DefaultRequestAuthHeaderProvider;
+import 
org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties;
+import org.apache.servicecomb.service.center.client.AddressManager;
+import org.apache.servicecomb.service.center.client.ServiceCenterClient;
+import org.apache.servicecomb.serviceregistry.config.ServiceRegistryConfig;
+import org.springframework.core.env.Environment;
+
+public class RBACBootStrapService implements BootStrapService {
+  private static final String RBAC_ADDRESS = 
"servicecomb.service.registry.address";
+
+  public static final String DEFAULT_REGISTRY_NAME = "default";
+
+  public static final String RBAC_ENABLED = 
"servicecomb.credentials.rbac.enabled";
+
+  public static final String ACCOUNT_NAME_KEY = 
"servicecomb.credentials.account.name";
+
+  public static final String PASSWORD_KEY = 
"servicecomb.credentials.account.password";
+
+  public static final String CIPHER_KEY = "servicecomb.credentials.cipher";
+
+  @Override
+  public void startup(Environment environment) {
+    if (!getBooleanProperty(environment, false, RBAC_ENABLED)) {
+      return;
+    }
+
+    AddressManager addressManager = createAddressManager(environment);
+    SSLProperties sslProperties = createSSLProperties(environment, 
"sc.consumer");
+    sslProperties.setEnabled(addressManager.address().startsWith("https://";));
+
+    // header: x-domain-name and url: /v1/{project}/ are all token from 
getTenantName。
+    ServiceCenterClient serviceCenterClient = new ServiceCenterClient(
+        addressManager, sslProperties, new DefaultRequestAuthHeaderProvider(), 
getTenantName(environment),
+        new HashMap<>(0)
+    );
+    Map<String, ServiceCenterClient> clients = new HashMap<>(1);
+    clients
+        .put(DEFAULT_REGISTRY_NAME, serviceCenterClient);
+    TokenCacheManager.getInstance().setServiceCenterClients(clients);
+    TokenCacheManager.getInstance().addTokenCache(
+        DEFAULT_REGISTRY_NAME,
+        getStringProperty(environment, null, ACCOUNT_NAME_KEY),
+        getStringProperty(environment, null, PASSWORD_KEY),
+        getCipher(getStringProperty(environment, DefaultCipher.CIPHER_NAME, 
CIPHER_KEY)));
+  }
+
+  private Cipher getCipher(String cipherName) {
+    if (DefaultCipher.CIPHER_NAME.equals(cipherName)) {
+      return DefaultCipher.getInstance();
+    }
+
+    Map<String, Cipher> cipherBeans = BeanUtils.getBeansOfType(Cipher.class);
+    return cipherBeans.values().stream().filter(c -> 
c.name().equals(cipherName)).findFirst()
+        .orElseThrow(() -> new IllegalArgumentException("failed to find cipher 
named " + cipherName));
+  }
+
+  private AddressManager createAddressManager(Environment environment) {
+    return new AddressManager(getTenantName(environment),
+        getRBACAddressList(environment));
+  }
+
+  private SSLProperties createSSLProperties(Environment environment, String 
tag) {
+    SSLProperties sslProperties = new SSLProperties();
+
+    SSLOption option = new SSLOption();
+    option.setEngine(getStringProperty(environment,
+        DEFAULT_OPTION.getEngine(),
+        "ssl." + tag + ".engine",
+        "ssl.engine"));
+    option.setProtocols(
+        getStringProperty(environment,
+            DEFAULT_OPTION.getProtocols(),
+            "ssl." + tag + ".protocols",
+            "ssl.protocols"));
+    option.setCiphers(
+        getStringProperty(environment, DEFAULT_OPTION.getCiphers(), "ssl." + 
tag + ".ciphers", "ssl.ciphers"));
+    option.setAuthPeer(
+        getBooleanProperty(environment, DEFAULT_OPTION.isAuthPeer(), "ssl." + 
tag + ".authPeer", "ssl.authPeer"));
+    option.setCheckCNHost(
+        getBooleanProperty(environment,
+            DEFAULT_OPTION.isCheckCNHost(),
+            "ssl." + tag + ".checkCN.host",
+            "ssl.checkCN.host"));
+    option.setCheckCNWhite(
+        getBooleanProperty(environment,
+            DEFAULT_OPTION.isCheckCNWhite(),
+            "ssl." + tag + ".checkCN.white",
+            "ssl.checkCN.white"));
+    option.setCheckCNWhiteFile(getStringProperty(environment,
+        DEFAULT_OPTION.getCiphers(),
+        "ssl." + tag + ".checkCN.white.file",
+        "ssl.checkCN.white.file"));
+    option.setAllowRenegociate(getBooleanProperty(environment,
+        DEFAULT_OPTION.isAllowRenegociate(),
+        "ssl." + tag + ".allowRenegociate",
+        "ssl.allowRenegociate"));
+    option.setStorePath(
+        getStringProperty(environment,
+            DEFAULT_OPTION.getStorePath(),
+            "ssl." + tag + ".storePath",
+            "ssl.storePath"));
+    option.setTrustStore(
+        getStringProperty(environment,
+            DEFAULT_OPTION.getTrustStore(),
+            "ssl." + tag + ".trustStore",
+            "ssl.trustStore"));
+    option.setTrustStoreType(getStringProperty(environment,
+        DEFAULT_OPTION.getTrustStoreType(),
+        "ssl." + tag + ".trustStoreType",
+        "ssl.trustStoreType"));
+    option.setTrustStoreValue(getStringProperty(environment,
+        DEFAULT_OPTION.getTrustStoreValue(),
+        "ssl." + tag + ".trustStoreValue",
+        "ssl.trustStoreValue"));
+    option.setKeyStore(
+        getStringProperty(environment, DEFAULT_OPTION.getKeyStore(), "ssl." + 
tag + ".keyStore", "ssl.keyStore"));
+    option.setKeyStoreType(
+        getStringProperty(environment,
+            DEFAULT_OPTION.getKeyStoreType(),
+            "ssl." + tag + ".keyStoreType",
+            "ssl.keyStoreType"));
+    option.setKeyStoreValue(getStringProperty(environment,
+        DEFAULT_OPTION.getKeyStoreValue(),
+        "ssl." + tag + ".keyStoreValue",
+        "ssl.keyStoreValue"));
+    option.setCrl(getStringProperty(environment, DEFAULT_OPTION.getCrl(), 
"ssl." + tag + ".crl", "ssl.crl"));
+    option.setSslCustomClass(
+        getStringProperty(environment, null, "ssl." + tag + ".sslCustomClass", 
"ssl.sslCustomClass"));
+
+    sslProperties.setSslOption(option);
+    
sslProperties.setSslCustom(SSLCustom.createSSLCustom(option.getSslCustomClass()));
+    return sslProperties;
+  }
+
+  private String getStringProperty(Environment environment, String 
defaultValue, String... keys) {
+    for (String key : keys) {
+      if (environment.getProperty(key) != null) {
+        return environment.getProperty(key);
+      }
+    }
+    return defaultValue;
+  }
+
+  private boolean getBooleanProperty(Environment environment, boolean 
defaultValue, String... keys) {
+    for (String key : keys) {
+      if (environment.getProperty(key) != null) {
+        return Boolean.parseBoolean(environment.getProperty(key));
+      }
+    }
+    return defaultValue;
+  }
+
+  private String getTenantName(Environment environment) {
+    return environment.getProperty(ServiceRegistryConfig.TENANT_NAME, 
ServiceRegistryConfig.NO_TENANT);
+  }
+
+  private List<String> getRBACAddressList(Environment environment) {
+    String address = environment.getProperty(RBAC_ADDRESS, 
"http://127.0.0.1:30100)");
+    return Arrays.asList(address.split(","));
+  }
+}
diff --git 
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/TokenAuthHeaderProvider.java
 
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/TokenAuthHeaderProvider.java
index 7b82a0e..0f07556 100644
--- 
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/TokenAuthHeaderProvider.java
+++ 
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/TokenAuthHeaderProvider.java
@@ -23,52 +23,11 @@ import java.util.Map;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.servicecomb.foundation.auth.AuthHeaderProvider;
-import org.apache.servicecomb.foundation.auth.Cipher;
-import org.apache.servicecomb.foundation.auth.DefaultCipher;
-import org.apache.servicecomb.foundation.common.utils.BeanUtils;
-import org.apache.servicecomb.serviceregistry.ServiceRegistry;
-
-import com.netflix.config.DynamicPropertyFactory;
 
 public class TokenAuthHeaderProvider implements AuthHeaderProvider {
-  public static final String ACCOUNT_NAME_KEY = 
"servicecomb.credentials.account.name";
-
-  public static final String PASSWORD_KEY = 
"servicecomb.credentials.account.password";
-
-  public static final String CIPHER_KEY = "servicecomb.credentials.cipher";
-
-  private String registryName;
-
-  private String accountName;
-
-  private String password;
-
-  private String cipherName;
-
-  public TokenAuthHeaderProvider() {
-    this.registryName = ServiceRegistry.DEFAULT_REGISTRY_NAME;
-    this.accountName = DynamicPropertyFactory.getInstance()
-        .getStringProperty(ACCOUNT_NAME_KEY, null).get();
-    this.password = DynamicPropertyFactory.getInstance()
-        .getStringProperty(PASSWORD_KEY, null).get();
-    this.cipherName = DynamicPropertyFactory.getInstance()
-        .getStringProperty(CIPHER_KEY, DefaultCipher.DEFAULT_CYPHER).get();
-    if (StringUtils.isNotEmpty(accountName)) {
-      TokenCacheManager.getInstance().addTokenCache(registryName, accountName, 
password, getCipher());
-    }
-  }
-
-  public TokenAuthHeaderProvider(String registryName, String accountName, 
String password, String cipherName) {
-    this.registryName = registryName;
-    this.accountName = accountName;
-    this.password = password;
-    this.cipherName = cipherName;
-    TokenCacheManager.getInstance().addTokenCache(this.registryName, 
this.accountName, this.password, getCipher());
-  }
-
   @Override
   public Map<String, String> authHeaders() {
-    String token = TokenCacheManager.getInstance().getToken(registryName);
+    String token = 
TokenCacheManager.getInstance().getToken(RBACBootStrapService.DEFAULT_REGISTRY_NAME);
     if (StringUtils.isEmpty(token)) {
       return new HashMap<>();
     }
@@ -77,14 +36,4 @@ public class TokenAuthHeaderProvider implements 
AuthHeaderProvider {
     header.put("Authorization", "Bearer " + token);
     return Collections.unmodifiableMap(header);
   }
-
-  private Cipher getCipher() {
-    if (DefaultCipher.DEFAULT_CYPHER.equals(cipherName)) {
-      return DefaultCipher.getInstance();
-    }
-
-    Map<String, Cipher> cipherBeans = BeanUtils.getBeansOfType(Cipher.class);
-    return cipherBeans.values().stream().filter(c -> 
c.name().equals(cipherName)).findFirst()
-        .orElseThrow(() -> new IllegalArgumentException("failed to find cipher 
named " + cipherName));
-  }
 }
diff --git 
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/TokenCacheManager.java
 
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/TokenCacheManager.java
index 248c25a..32d7635 100644
--- 
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/TokenCacheManager.java
+++ 
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/TokenCacheManager.java
@@ -35,12 +35,9 @@ import org.apache.servicecomb.foundation.auth.Cipher;
 import 
org.apache.servicecomb.foundation.common.concurrency.SuppressedRunnableWrapper;
 import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
 import org.apache.servicecomb.foundation.common.utils.TimeUtils;
-import org.apache.servicecomb.foundation.vertx.client.http.HttpClients;
-import org.apache.servicecomb.serviceregistry.RegistryUtils;
-import org.apache.servicecomb.serviceregistry.ServiceRegistry;
-import org.apache.servicecomb.serviceregistry.api.request.RbacTokenRequest;
-import org.apache.servicecomb.serviceregistry.api.response.RbacTokenResponse;
-import org.apache.servicecomb.serviceregistry.client.ServiceRegistryClient;
+import org.apache.servicecomb.service.center.client.ServiceCenterClient;
+import org.apache.servicecomb.service.center.client.model.RbacTokenRequest;
+import org.apache.servicecomb.service.center.client.model.RbacTokenResponse;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -55,6 +52,8 @@ public final class TokenCacheManager {
 
   private Map<String, TokenCache> tokenCacheMap;
 
+  private Map<String, ServiceCenterClient> serviceCenterClients;
+
   public static TokenCacheManager getInstance() {
     return INSTANCE;
   }
@@ -73,6 +72,10 @@ public final class TokenCacheManager {
     tokenCacheMap = new ConcurrentHashMapEx<>();
   }
 
+  public void setServiceCenterClients(Map<String, ServiceCenterClient> 
serviceCenterClients) {
+    this.serviceCenterClients = serviceCenterClients;
+  }
+
   public void addTokenCache(String registryName, String accountName, String 
password, Cipher cipher) {
     Objects.requireNonNull(registryName, "registryName should not be null!");
     if (tokenCacheMap.containsKey(registryName)) {
@@ -83,8 +86,6 @@ public final class TokenCacheManager {
     TokenCache tokenCache = new TokenCache(registryName, accountName, 
password, cipher, this.clock);
     tokenCache.setTokenCacheWorker(this.tokenCacheWorker);
     tokenCacheMap.put(registryName, tokenCache);
-    HttpClients.load();
-    RegistryUtils.init();
     tokenCache.refreshToken();
   }
 
@@ -94,7 +95,7 @@ public final class TokenCacheManager {
         .orElse("");
   }
 
-  public static class TokenCache {
+  public class TokenCache {
     private final String registryName;
 
     private final String accountName;
@@ -160,20 +161,12 @@ public final class TokenCacheManager {
     }
 
     private void refreshToken() {
-      ServiceRegistry serviceRegistry = 
RegistryUtils.getServiceRegistry(registryName);
-      ServiceRegistryClient serviceRegistryClient =
-          serviceRegistry == null ? null : 
serviceRegistry.getServiceRegistryClient();
-      if ((serviceRegistry == null || serviceRegistryClient == null)
-          && ServiceRegistry.DEFAULT_REGISTRY_NAME.equals(registryName)) {
-        LOGGER.error("failed to get default serviceRegistry");
-        tokenCacheWorker.schedule( // retry after 1 second
-            this::refreshToken, 1, TimeUnit.SECONDS);
-        return;
-      }
+      ServiceCenterClient serviceCenterClient = 
serviceCenterClients.get(this.registryName);
+
       RbacTokenRequest request = new RbacTokenRequest();
-      request.setAccountName(new 
String(cipher.decrypt(accountName.toCharArray())));
+      request.setName(new String(cipher.decrypt(accountName.toCharArray())));
       request.setPassword(new String(cipher.decrypt(password.toCharArray())));
-      RbacTokenResponse rbacTokenResponse = 
serviceRegistryClient.getRbacToken(request);
+      RbacTokenResponse rbacTokenResponse = 
serviceCenterClient.queryToken(request);
       LOGGER.info("refresh token successfully {}", 
rbacTokenResponse.getStatusCode());
       if (StringUtils.isEmpty(this.token)) {
         if (Status.UNAUTHORIZED.getStatusCode() == 
rbacTokenResponse.getStatusCode()) {
@@ -188,7 +181,6 @@ public final class TokenCacheManager {
       }
       this.token = rbacTokenResponse.getToken();
       this.nextRefreshTime = clock.millis() + tokenLife;
-
     }
   }
 }
diff --git 
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/ServiceRegistryClient.java
 
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/ServiceRegistryClient.java
index ab028b1..902a107 100644
--- 
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/ServiceRegistryClient.java
+++ 
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/ServiceRegistryClient.java
@@ -27,10 +27,8 @@ import 
org.apache.servicecomb.registry.api.registry.MicroserviceInstance;
 import org.apache.servicecomb.registry.api.registry.MicroserviceInstanceStatus;
 import org.apache.servicecomb.registry.api.registry.MicroserviceInstances;
 import org.apache.servicecomb.serviceregistry.api.registry.ServiceCenterInfo;
-import org.apache.servicecomb.serviceregistry.api.request.RbacTokenRequest;
 import org.apache.servicecomb.serviceregistry.api.response.GetSchemaResponse;
 import org.apache.servicecomb.serviceregistry.api.response.HeartbeatResponse;
-import org.apache.servicecomb.serviceregistry.api.response.RbacTokenResponse;
 import org.apache.servicecomb.serviceregistry.client.http.Holder;
 
 public interface ServiceRegistryClient {
@@ -204,6 +202,4 @@ public interface ServiceRegistryClient {
    * @return whether this operation success
    */
   boolean updateMicroserviceInstanceStatus(String microserviceId, String 
instanceId, MicroserviceInstanceStatus status);
-
-  RbacTokenResponse getRbacToken(RbacTokenRequest request);
 }
diff --git 
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/http/ServiceRegistryClientImpl.java
 
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/http/ServiceRegistryClientImpl.java
index a96908d..bc8ed80 100644
--- 
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/http/ServiceRegistryClientImpl.java
+++ 
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/http/ServiceRegistryClientImpl.java
@@ -43,11 +43,9 @@ import 
org.apache.servicecomb.registry.api.registry.MicroserviceInstanceStatus;
 import org.apache.servicecomb.registry.api.registry.MicroserviceInstances;
 import org.apache.servicecomb.serviceregistry.RegistryUtils;
 import org.apache.servicecomb.serviceregistry.api.Const;
-import org.apache.servicecomb.serviceregistry.api.Const.REGISTRY_API;
 import org.apache.servicecomb.serviceregistry.api.registry.ServiceCenterInfo;
 import org.apache.servicecomb.serviceregistry.api.request.CreateSchemaRequest;
 import org.apache.servicecomb.serviceregistry.api.request.CreateServiceRequest;
-import org.apache.servicecomb.serviceregistry.api.request.RbacTokenRequest;
 import 
org.apache.servicecomb.serviceregistry.api.request.RegisterInstanceRequest;
 import 
org.apache.servicecomb.serviceregistry.api.request.UpdatePropertiesRequest;
 import 
org.apache.servicecomb.serviceregistry.api.response.CreateServiceResponse;
@@ -59,7 +57,6 @@ import 
org.apache.servicecomb.serviceregistry.api.response.GetSchemasResponse;
 import org.apache.servicecomb.serviceregistry.api.response.GetServiceResponse;
 import org.apache.servicecomb.serviceregistry.api.response.HeartbeatResponse;
 import 
org.apache.servicecomb.serviceregistry.api.response.MicroserviceInstanceResponse;
-import org.apache.servicecomb.serviceregistry.api.response.RbacTokenResponse;
 import 
org.apache.servicecomb.serviceregistry.api.response.RegisterInstanceResponse;
 import org.apache.servicecomb.serviceregistry.client.ClientException;
 import org.apache.servicecomb.serviceregistry.client.IpPortManager;
@@ -70,7 +67,6 @@ import 
org.apache.servicecomb.serviceregistry.task.MicroserviceInstanceHeartbeat
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
@@ -959,37 +955,4 @@ public final class ServiceRegistryClientImpl implements 
ServiceRegistryClient {
       ipPortManager.initAutoDiscovery();
     }
   }
-
-  @Override
-  public RbacTokenResponse getRbacToken(RbacTokenRequest request) {
-    Holder<RbacTokenResponse> holder = new Holder<>();
-    IpPort ipPort = ipPortManager.getAvailableAddress();
-
-    byte[] requestBody;
-    try {
-      requestBody = JsonUtils.writeValueAsBytes(request);
-    } catch (JsonProcessingException e) {
-      LOGGER.error("failed to write request as byte array");
-      return new RbacTokenResponse();
-    }
-
-    CountDownLatch countDownLatch = new CountDownLatch(1);
-    restClientUtil.post(ipPort, REGISTRY_API.RBAC_TOKEN,
-        new RequestParam().setBody(requestBody),
-        syncHandler(countDownLatch, RbacTokenResponse.class, holder));
-    try {
-      countDownLatch.await();
-    } catch (InterruptedException e) {
-      LOGGER.error("failed to wait for rbac token response", e);
-    }
-
-    if (holder.value != null) {
-      holder.value.setStatusCode(holder.getStatusCode());
-      return holder.value;
-    }
-
-    RbacTokenResponse response = new RbacTokenResponse();
-    response.setStatusCode(holder.getStatusCode());
-    return response;
-  }
 }
diff --git 
a/foundations/foundation-common/src/test/resources/META-INF/services/org.apache.servicecomb.foundation.common.utils.SPIServiceDef
 
b/service-registry/registry-service-center/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.bootstrap.BootStrapService
similarity index 92%
rename from 
foundations/foundation-common/src/test/resources/META-INF/services/org.apache.servicecomb.foundation.common.utils.SPIServiceDef
rename to 
service-registry/registry-service-center/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.bootstrap.BootStrapService
index eebf462..e515f0a 100644
--- 
a/foundations/foundation-common/src/test/resources/META-INF/services/org.apache.servicecomb.foundation.common.utils.SPIServiceDef
+++ 
b/service-registry/registry-service-center/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.bootstrap.BootStrapService
@@ -15,4 +15,4 @@
 # limitations under the License.
 #
 
-org.apache.servicecomb.foundation.common.utils.SPIServiceDefImpl
\ No newline at end of file
+org.apache.servicecomb.serviceregistry.auth.RBACBootStrapService
\ No newline at end of file
diff --git 
a/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/client/LocalServiceRegistryClientImpl.java
 
b/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/client/LocalServiceRegistryClientImpl.java
index 4c7183e..a63e9b2 100644
--- 
a/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/client/LocalServiceRegistryClientImpl.java
+++ 
b/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/client/LocalServiceRegistryClientImpl.java
@@ -43,10 +43,8 @@ import 
org.apache.servicecomb.registry.version.VersionRuleUtils;
 import org.apache.servicecomb.registry.version.VersionUtils;
 import org.apache.servicecomb.serviceregistry.api.registry.ServiceCenterConfig;
 import org.apache.servicecomb.serviceregistry.api.registry.ServiceCenterInfo;
-import org.apache.servicecomb.serviceregistry.api.request.RbacTokenRequest;
 import org.apache.servicecomb.serviceregistry.api.response.GetSchemaResponse;
 import org.apache.servicecomb.serviceregistry.api.response.HeartbeatResponse;
-import org.apache.servicecomb.serviceregistry.api.response.RbacTokenResponse;
 import org.apache.servicecomb.serviceregistry.client.http.Holder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -457,9 +455,4 @@ public class LocalServiceRegistryClientImpl implements 
ServiceRegistryClient {
     microserviceInstance.setStatus(status);
     return true;
   }
-
-  @Override
-  public RbacTokenResponse getRbacToken(RbacTokenRequest request) {
-    return new RbacTokenResponse();
-  }
 }
diff --git 
a/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/client/http/TestServiceRegistryClientImpl.java
 
b/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/client/http/TestServiceRegistryClientImpl.java
index 87d022f..1d69a18 100644
--- 
a/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/client/http/TestServiceRegistryClientImpl.java
+++ 
b/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/client/http/TestServiceRegistryClientImpl.java
@@ -20,7 +20,6 @@ package org.apache.servicecomb.serviceregistry.client.http;
 import static org.hamcrest.core.Is.is;
 import static org.junit.Assert.fail;
 
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -30,13 +29,11 @@ import java.util.concurrent.TimeUnit;
 
 import javax.ws.rs.core.Response.Status;
 
-import org.apache.commons.configuration.Configuration;
 import org.apache.log4j.Appender;
 import org.apache.log4j.Logger;
 import org.apache.log4j.spi.LoggingEvent;
 import org.apache.servicecomb.config.BootStrapProperties;
 import org.apache.servicecomb.foundation.common.net.IpPort;
-import org.apache.servicecomb.foundation.common.utils.JsonUtils;
 import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils;
 import org.apache.servicecomb.foundation.vertx.client.http.HttpClients;
 import org.apache.servicecomb.registry.api.registry.Microservice;
@@ -46,12 +43,10 @@ import 
org.apache.servicecomb.registry.definition.DefinitionConst;
 import org.apache.servicecomb.serviceregistry.RegistryUtils;
 import org.apache.servicecomb.serviceregistry.api.registry.ServiceCenterConfig;
 import org.apache.servicecomb.serviceregistry.api.registry.ServiceCenterInfo;
-import org.apache.servicecomb.serviceregistry.api.request.RbacTokenRequest;
 import 
org.apache.servicecomb.serviceregistry.api.response.GetExistenceResponse;
 import org.apache.servicecomb.serviceregistry.api.response.GetSchemaResponse;
 import org.apache.servicecomb.serviceregistry.api.response.GetSchemasResponse;
 import org.apache.servicecomb.serviceregistry.api.response.GetServiceResponse;
-import org.apache.servicecomb.serviceregistry.api.response.RbacTokenResponse;
 import org.apache.servicecomb.serviceregistry.client.ClientException;
 import 
org.apache.servicecomb.serviceregistry.client.http.ServiceRegistryClientImpl.ResponseWrapper;
 import org.apache.servicecomb.serviceregistry.config.ServiceRegistryConfig;
@@ -628,103 +623,4 @@ public class TestServiceRegistryClientImpl {
   private void shouldThrowException() {
     fail("an exception is expected");
   }
-
-  @Test
-  public void getRbacToken() {
-    mockForGetRbacToken(200, "{\"token\":\"test_token_content\"}");
-    RbacTokenRequest request = new RbacTokenRequest();
-    request.setAccountName("test_account_name");
-    request.setPassword("test_password");
-    RbacTokenResponse response = oClient.getRbacToken(request);
-
-    Assert.assertEquals(200, response.getStatusCode());
-    Assert.assertEquals("test_token_content", response.getToken());
-  }
-
-  @Test
-  public void getRbacToken_waiting_response_interrupted() {
-    InterruptedException e = new InterruptedException();
-    new MockUp<CountDownLatch>() {
-      @Mock
-      public void await() throws InterruptedException {
-        throw e;
-      }
-    };
-    new MockUp<RestClientUtil>() {
-      @Mock
-      void post(IpPort ipPort, String uri, RequestParam requestParam,
-          Handler<RestResponse> responseHandler) {
-      }
-    };
-    RbacTokenRequest request = new RbacTokenRequest();
-    request.setAccountName("test_account_name");
-    request.setPassword("test_password");
-
-    RbacTokenResponse response = oClient.getRbacToken(request);
-
-    Assert.assertEquals(0, response.getStatusCode());
-    Assert.assertNull(response.getToken());
-  }
-
-  @Test
-  public void getRbacToken_serialize_request_exception() {
-    mockForGetRbacToken(200, "{\"token\":\"test_token_content\"}");
-    RbacTokenRequest request = new RbacTokenRequest() {
-      @Override
-      public String getAccountName() {
-        throw new IllegalStateException("mock serialization error");
-      }
-    };
-    request.setAccountName("test_account_name");
-    request.setPassword("test_password");
-
-    RbacTokenResponse response = oClient.getRbacToken(request);
-
-    Assert.assertEquals(0, response.getStatusCode());
-    Assert.assertNull(response.getToken());
-  }
-
-  @Test
-  public void getRbacToken_auth_failed() {
-    mockForGetRbacToken(401, "{\"detail\":\"wrong user name or password\","
-        + "\"errorCode\":\"401002\","
-        + "\"errorMessage\":\"Request unauthorized\"}");
-    RbacTokenRequest request = new RbacTokenRequest();
-    request.setAccountName("test_account_name");
-    request.setPassword("test_password");
-    RbacTokenResponse response = oClient.getRbacToken(request);
-
-    Assert.assertEquals(401, response.getStatusCode());
-    Assert.assertNull(response.getToken());
-  }
-
-  private void mockForGetRbacToken(final int responseStatusCode, final String 
responseBody) {
-    new MockUp<RestClientUtil>() {
-      @Mock
-      void post(IpPort ipPort, String uri, RequestParam requestParam, 
Handler<RestResponse> responseHandler) {
-        Assert.assertEquals("/v4/token", uri);
-        try {
-          RbacTokenRequest rbacTokenRequest = 
JsonUtils.readValue(requestParam.getBody(), RbacTokenRequest.class);
-          Assert.assertEquals("test_account_name", 
rbacTokenRequest.getAccountName());
-          Assert.assertEquals("test_password", rbacTokenRequest.getPassword());
-        } catch (IOException e) {
-          fail("malformed request body");
-          e.printStackTrace();
-        }
-        HttpClientResponse httpClientResponse = new 
MockUp<HttpClientResponse>() {
-          @Mock
-          int statusCode() {
-            return responseStatusCode;
-          }
-
-          @Mock
-          HttpClientResponse bodyHandler(Handler<Buffer> bodyHandler) {
-            bodyHandler.handle(Buffer.buffer(responseBody));
-            return null;
-          }
-        }.getMockInstance();
-        responseHandler.handle(new RestResponse(null, httpClientResponse));
-      }
-    };
-  }
 }
diff --git a/solutions/solution-basic/pom.xml b/solutions/solution-basic/pom.xml
index 4b11f84..952d7e2 100644
--- a/solutions/solution-basic/pom.xml
+++ b/solutions/solution-basic/pom.xml
@@ -96,10 +96,14 @@
       <artifactId>metrics-core</artifactId>
     </dependency>
 
-    <!-- inspector -->
+    <!-- servicestage -->
     <dependency>
       <groupId>org.apache.servicecomb</groupId>
-      <artifactId>inspector</artifactId>
+      <artifactId>servicestage</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.servicecomb</groupId>
+      <artifactId>config-cc</artifactId>
     </dependency>
 
   </dependencies>

Reply via email to