Skip to content

Commit

Permalink
[Enhancement](HttpServer) Add http interface authentication (apache#1…
Browse files Browse the repository at this point in the history
…6571)

1. Organize http documents
2. Add http interface authentication for FE
3. Support https interface for FE
4. Provide authentication interface
5. Add http interface authentication for BE
6. Support https interface for BE
  • Loading branch information
yongjinhou authored Feb 24, 2023
1 parent a12b3c3 commit c3538ca
Show file tree
Hide file tree
Showing 13 changed files with 85 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,11 @@ public class Config extends ConfigBase {
*/
@ConfField public static int http_port = 8030;

/**
* Whether to enable all http interface authentication
*/
@ConfField public static boolean enable_all_http_auth = false;

/**
* Jetty container default configuration
* Jetty's thread architecture model is very simple, divided into three thread pools:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,10 @@ public Object check(HttpServletRequest request, HttpServletResponse response) th

@RequestMapping(value = "/dump", method = RequestMethod.GET)
public Object dump(HttpServletRequest request, HttpServletResponse response) throws DdlException {
if (Config.enable_all_http_auth) {
executeCheckPassword(request, response);
}

/*
* Before dump, we acquired the catalog read lock and all databases' read lock and all
* the jobs' read lock. This will guarantee the consistency of database and job queues.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ public class BackendsAction extends RestBaseController {

@RequestMapping(path = "/api/backends", method = {RequestMethod.GET})
public Object getBackends(HttpServletRequest request, HttpServletResponse response) {
/**
* As required, the interface should require user have GlobalAuth-PrivPredicate.ADMIN permission.
* However, a user who uses spark-doris-connector/flink-doris-connector does not have corresponding permission.
* To ensure that the connector works properly, we do not verify the permission of the interface.
*/
executeCheckPassword(request, response);

boolean needAlive = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
* }
*/
@RestController
public class BootstrapFinishAction {
public class BootstrapFinishAction extends RestBaseController {

private static final String CLUSTER_ID = "cluster_id";
private static final String TOKEN = "token";
Expand All @@ -58,6 +58,10 @@ public class BootstrapFinishAction {

@RequestMapping(path = "/api/bootstrap", method = RequestMethod.GET)
public ResponseEntity execute(HttpServletRequest request, HttpServletResponse response) {
if (Config.enable_all_http_auth) {
executeCheckPassword(request, response);
}

boolean isReady = Env.getCurrentEnv().isReady();

// to json response
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,13 @@
* This Api will return the path configured in Config.http_api_extra_base_path.
*/
@RestController
public class ExtraBasepathAction {
public class ExtraBasepathAction extends RestBaseController {
@RequestMapping(path = "/api/basepath", method = RequestMethod.GET)
public ResponseEntity execute(HttpServletRequest request, HttpServletResponse response) {
if (Config.enable_all_http_auth) {
executeCheckPassword(request, response);
}

BasepathResponse resp = new BasepathResponse();
resp.path = Config.http_api_extra_base_path;
if (Strings.isNullOrEmpty(Config.http_api_extra_base_path)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@
package org.apache.doris.httpv2.rest;

import org.apache.doris.catalog.Env;
import org.apache.doris.common.Config;
import org.apache.doris.common.util.SmallFileMgr;
import org.apache.doris.httpv2.entity.ResponseEntityBuilder;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.qe.ConnectContext;

import com.google.common.base.Strings;
import org.apache.logging.log4j.LogManager;
Expand All @@ -38,6 +41,11 @@ public class GetSmallFileAction extends RestBaseController {

@RequestMapping(path = "/api/get_small_file", method = RequestMethod.GET)
public Object execute(HttpServletRequest request, HttpServletResponse response) {
if (Config.enable_all_http_auth) {
executeCheckPassword(request, response);
checkGlobalAuth(ConnectContext.get().getCurrentUserIdentity(), PrivPredicate.ADMIN);
}

String token = request.getParameter("token");
String fileIdStr = request.getParameter("file_id");
// check param empty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package org.apache.doris.httpv2.rest;

import org.apache.doris.catalog.Env;
import org.apache.doris.common.Config;
import org.apache.doris.httpv2.entity.ResponseEntityBuilder;

import org.springframework.web.bind.annotation.RequestMapping;
Expand All @@ -26,12 +27,18 @@

import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@RestController
public class HealthAction extends RestBaseController {

@RequestMapping(path = "/api/health", method = RequestMethod.GET)
public Object execute() {
public Object execute(HttpServletRequest request, HttpServletResponse response) {
if (Config.enable_all_http_auth) {
executeCheckPassword(request, response);
}

Map<String, Object> result = new HashMap<>();
result.put("total_backend_num", Env.getCurrentSystemInfo().getBackendIds(false).size());
result.put("online_backend_num", Env.getCurrentSystemInfo().getBackendIds(true).size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.apache.doris.catalog.OlapTable;
import org.apache.doris.catalog.Table;
import org.apache.doris.cluster.ClusterNamespace;
import org.apache.doris.common.Config;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.FeConstants;
import org.apache.doris.common.MetaNotFoundException;
Expand Down Expand Up @@ -86,7 +87,8 @@ public class MetaInfoAction extends RestBaseController {
public Object getAllDatabases(
@PathVariable(value = NS_KEY) String ns,
HttpServletRequest request, HttpServletResponse response) {
checkWithCookie(request, response, false);
boolean checkAuth = Config.enable_all_http_auth ? true : false;
checkWithCookie(request, response, checkAuth);

// use NS_KEY as catalog, but NS_KEY's default value is 'default_cluster'.
if (ns.equalsIgnoreCase(SystemInfoService.DEFAULT_CLUSTER)) {
Expand Down Expand Up @@ -133,7 +135,8 @@ public Object getAllDatabases(
public Object getTables(
@PathVariable(value = NS_KEY) String ns, @PathVariable(value = DB_KEY) String dbName,
HttpServletRequest request, HttpServletResponse response) {
checkWithCookie(request, response, false);
boolean checkAuth = Config.enable_all_http_auth ? true : false;
checkWithCookie(request, response, checkAuth);

if (!ns.equalsIgnoreCase(SystemInfoService.DEFAULT_CLUSTER)) {
return ResponseEntityBuilder.badRequest("Only support 'default_cluster' now");
Expand Down Expand Up @@ -209,7 +212,8 @@ public Object getTableSchema(
@PathVariable(value = NS_KEY) String ns, @PathVariable(value = DB_KEY) String dbName,
@PathVariable(value = TABLE_KEY) String tblName,
HttpServletRequest request, HttpServletResponse response) throws UserException {
checkWithCookie(request, response, false);
boolean checkAuth = Config.enable_all_http_auth ? true : false;
checkWithCookie(request, response, checkAuth);

if (!ns.equalsIgnoreCase(SystemInfoService.DEFAULT_CLUSTER)) {
return ResponseEntityBuilder.badRequest("Only support 'default_cluster' now");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.apache.doris.httpv2.rest;

import org.apache.doris.common.Config;
import org.apache.doris.metric.JsonMetricVisitor;
import org.apache.doris.metric.MetricRepo;
import org.apache.doris.metric.MetricVisitor;
Expand All @@ -34,12 +35,16 @@
//fehost:port/metrics
//fehost:port/metrics?type=core
@RestController
public class MetricsAction {
public class MetricsAction extends RestBaseController {

private static final String TYPE_PARAM = "type";

@RequestMapping(path = "/metrics")
public void execute(HttpServletRequest request, HttpServletResponse response) {
if (Config.enable_all_http_auth) {
executeCheckPassword(request, response);
}

String type = request.getParameter(TYPE_PARAM);
MetricVisitor visitor = null;
if (!Strings.isNullOrEmpty(type) && type.equalsIgnoreCase("core")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ public static Action getAction(String str) {

@RequestMapping(path = "/api/show_meta_info", method = RequestMethod.GET)
public Object show_meta_info(HttpServletRequest request, HttpServletResponse response) {
if (Config.enable_all_http_auth) {
executeCheckPassword(request, response);
checkGlobalAuth(ConnectContext.get().getCurrentUserIdentity(), PrivPredicate.ADMIN);
}

String action = request.getParameter("action");
if (Strings.isNullOrEmpty(action)) {
return ResponseEntityBuilder.badRequest("Missing action parameter");
Expand Down Expand Up @@ -143,6 +148,11 @@ public Object show_proc(HttpServletRequest request, HttpServletResponse response

@RequestMapping(path = "/api/show_runtime_info", method = RequestMethod.GET)
public Object show_runtime_info(HttpServletRequest request, HttpServletResponse response) {
if (Config.enable_all_http_auth) {
executeCheckPassword(request, response);
checkGlobalAuth(ConnectContext.get().getCurrentUserIdentity(), PrivPredicate.ADMIN);
}

HashMap<String, String> feInfo = new HashMap<String, String>();

// Get memory info
Expand All @@ -164,6 +174,10 @@ public Object show_runtime_info(HttpServletRequest request, HttpServletResponse

@RequestMapping(path = "/api/show_data", method = RequestMethod.GET)
public Object show_data(HttpServletRequest request, HttpServletResponse response) {
if (Config.enable_all_http_auth) {
executeCheckPassword(request, response);
checkGlobalAuth(ConnectContext.get().getCurrentUserIdentity(), PrivPredicate.ADMIN);
}

Map<String, Long> oneEntry = Maps.newHashMap();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@
import org.apache.doris.analysis.StatementBase;
import org.apache.doris.catalog.Env;
import org.apache.doris.catalog.TableIf;
import org.apache.doris.common.Config;
import org.apache.doris.common.util.SqlParserUtils;
import org.apache.doris.datasource.InternalCatalog;
import org.apache.doris.httpv2.entity.ResponseEntityBuilder;
import org.apache.doris.httpv2.util.ExecutionResultSet;
import org.apache.doris.httpv2.util.StatementSubmitter;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.system.SystemInfoService;

Expand Down Expand Up @@ -83,6 +85,10 @@ public class StmtExecutionAction extends RestBaseController {
public Object executeSQL(@PathVariable(value = NS_KEY) String ns, @PathVariable(value = DB_KEY) String dbName,
HttpServletRequest request, HttpServletResponse response, @RequestBody String body) {
ActionAuthorizationInfo authInfo = checkWithCookie(request, response, false);
String fullDbName = getFullDbName(dbName);
if (Config.enable_all_http_auth) {
checkDbAuth(ConnectContext.get().getCurrentUserIdentity(), fullDbName, PrivPredicate.ADMIN);
}

if (ns.equalsIgnoreCase(SystemInfoService.DEFAULT_CLUSTER)) {
ns = InternalCatalog.INTERNAL_CATALOG_NAME;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@
package org.apache.doris.httpv2.restv2;

import org.apache.doris.analysis.BrokerDesc;
import org.apache.doris.common.Config;
import org.apache.doris.common.UserException;
import org.apache.doris.common.parquet.ParquetReader;
import org.apache.doris.common.util.BrokerUtil;
import org.apache.doris.httpv2.entity.ResponseEntityBuilder;
import org.apache.doris.httpv2.rest.RestBaseController;
import org.apache.doris.thrift.TBrokerFileStatus;

import com.google.common.collect.Lists;
Expand All @@ -42,7 +44,7 @@

@RestController
@RequestMapping("/rest/v2")
public class ImportAction {
public class ImportAction extends RestBaseController {

private static final Logger LOG = LogManager.getLogger(ImportAction.class);

Expand Down Expand Up @@ -74,6 +76,10 @@ public class ImportAction {
@RequestMapping(path = "/api/import/file_review", method = RequestMethod.POST)
public Object fileReview(@RequestBody FileReviewRequestVo body,
HttpServletRequest request, HttpServletResponse response) {
if (Config.enable_all_http_auth) {
executeCheckPassword(request, response);
}

FileInfo fileInfo = body.getFileInfo();
ConnectInfo connectInfo = body.getConnectInfo();
BrokerDesc brokerDesc = new BrokerDesc(connectInfo.getBrokerName(), connectInfo.getBrokerProps());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package org.apache.doris.httpv2.restv2;

import org.apache.doris.catalog.Env;
import org.apache.doris.common.Config;
import org.apache.doris.datasource.InternalCatalog;
import org.apache.doris.httpv2.entity.ResponseEntityBuilder;
import org.apache.doris.httpv2.rest.RestBaseController;
Expand Down Expand Up @@ -45,6 +46,10 @@ public class StatisticAction extends RestBaseController {

@RequestMapping(path = "/api/cluster_overview", method = RequestMethod.GET)
public Object clusterOverview(HttpServletRequest request, HttpServletResponse response) {
if (Config.enable_all_http_auth) {
executeCheckPassword(request, response);
}

if (!Env.getCurrentEnv().isMaster()) {
return redirectToMaster(request, response);
}
Expand Down

0 comments on commit c3538ca

Please sign in to comment.