未验证 提交 3fd3d99b 编写于 作者: T tcf1207239873 提交者: GitHub

Merge pull request #4 from didi/dev

Dev-0518-2
......@@ -210,11 +210,11 @@ CREATE TABLE `gateway_config` (
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_type_name` (`type`,`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='gateway配置';
INSERT INTO gateway_config(type, name, value, `version`) values('SERVICE_DISCOVERY_QUEUE_SIZE', 'SERVICE_DISCOVERY_QUEUE_SIZE', 100000000, 1);
INSERT INTO gateway_config(type, name, value, `version`) values('SERVICE_DISCOVERY_APPID_RATE', 'SERVICE_DISCOVERY_APPID_RATE', 100000000, 1);
INSERT INTO gateway_config(type, name, value, `version`) values('SERVICE_DISCOVERY_IP_RATE', 'SERVICE_DISCOVERY_IP_RATE', 100000000, 1);
INSERT INTO gateway_config(type, name, value, `version`) values('SERVICE_DISCOVERY_SP_RATE', 'app_01234567', 100000000, 1);
INSERT INTO gateway_config(type, name, value, `version`) values('SERVICE_DISCOVERY_SP_RATE', '192.168.0.1', 100000000, 1);
INSERT INTO gateway_config(type, name, value, `version`, `description`) values('SD_QUEUE_SIZE', 'SD_QUEUE_SIZE', 100000000, 1, '任意集群队列大小');
INSERT INTO gateway_config(type, name, value, `version`, `description`) values('SD_APP_RATE', 'SD_APP_RATE', 100000000, 1, '任意一个App限速');
INSERT INTO gateway_config(type, name, value, `version`, `description`) values('SD_IP_RATE', 'SD_IP_RATE', 100000000, 1, '任意一个IP限速');
INSERT INTO gateway_config(type, name, value, `version`, `description`) values('SD_SP_RATE', 'app_01234567', 100000000, 1, '指定App限速');
INSERT INTO gateway_config(type, name, value, `version`, `description`) values('SD_SP_RATE', '192.168.0.1', 100000000, 1, '指定IP限速');
--
-- Table structure for table `heartbeat`
......
---
![kafka-manager-logo](../assets/images/common/logo_name.png)
**一站式`Apache Kafka`集群指标监控与运维管控平台**
---
# 登录绕过
## 背景
现在除了开放出来的第三方接口,其他接口都需要走登录认证。
但是第三方接口不多,开放出来的能力有限,但是登录的接口又需要登录,非常的麻烦。
因此,新增了一个登录绕过的功能,为一些紧急临时的需求,提供一个调用不需要登录的能力。
## 使用方式
步骤一:接口调用时,在header中,增加如下信息:
```shell
# 表示开启登录绕过
Trick-Login-Switch : on
# 登录绕过的用户, 这里可以是admin, 或者是其他的, 但是必须在运维管控->平台管理->用户管理中设置了该用户。
Trick-Login-User : admin
```
 
步骤二:在运维管控->平台管理->平台配置上,设置允许了该用户以绕过的方式登录
```shell
# 设置的key,必须是这个
SECURITY.TRICK_USERS
# 设置的value,是json数组的格式,例如
[ "admin", "logi"]
```
 
步骤三:解释说明
设置完成上面两步之后,就可以直接调用需要登录的接口了。
但是还有一点需要注意,绕过的用户仅能调用他有权限的接口,比如一个普通用户,那么他就只能调用普通的接口,不能去调用运维人员的接口。
......@@ -27,6 +27,7 @@
- 15、APP(应用)如何被使用起来?
- 16、为什么下线应用提示operation forbidden?
- 17、删除Topic成功,为什么过一会儿之后又出现了?
- 18、如何在不登录的情况下,调用一些需要登录的接口?
---
......@@ -195,3 +196,7 @@ for (int i= 0; i < 100000; ++i) {
producer.send(new ProducerRecord<String, String>("logi_km" + i,"hello logi_km"));
}
```
### 18、如何在不登录的情况下,调用一些需要登录的接口?
具体见:[登录绕过](./call_api_bypass_login.md)
package com.xiaojukeji.kafka.manager.common.bizenum;
/**
* @author zengqiao
* @date 20/7/27
*/
public enum ApiLevelEnum {
LEVEL_0(0),
LEVEL_1(1),
LEVEL_2(2),
LEVEL_3(3)
;
private int level;
ApiLevelEnum(int level) {
this.level = level;
}
}
\ No newline at end of file
......@@ -24,18 +24,10 @@ public enum ConsumeHealthEnum {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String toString() {
return "ConsumeHealthEnum{" +
......
......@@ -19,7 +19,10 @@ public enum DBStatusEnum {
return status;
}
public void setStatus(int status) {
this.status = status;
@Override
public String toString() {
return "DBStatusEnum{" +
"status=" + status +
'}';
}
}
\ No newline at end of file
......@@ -21,18 +21,10 @@ public enum IDCEnum {
return idc;
}
public void setIdc(String idc) {
this.idc = idc;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "IDCEnum{" +
......
......@@ -21,10 +21,6 @@ public enum KafkaBrokerRoleEnum {
return role;
}
public void setRole(String role) {
this.role = role;
}
@Override
public String toString() {
return "KafkaBrokerRoleEnum{" +
......
......@@ -24,18 +24,10 @@ public enum KafkaClientEnum {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "KafkaClientEnum{" +
......
......@@ -18,4 +18,11 @@ public enum OffsetResetTypeEnum {
public Integer getCode() {
return code;
}
@Override
public String toString() {
return "OffsetResetTypeEnum{" +
"code=" + code +
'}';
}
}
......@@ -27,4 +27,12 @@ public enum OperationStatusEnum {
public String getMessage() {
return message;
}
@Override
public String toString() {
return "OperationStatusEnum{" +
"code=" + code +
", message='" + message + '\'' +
'}';
}
}
\ No newline at end of file
......@@ -15,9 +15,9 @@ public enum PeakFlowStatusEnum {
;
public Integer code;
private Integer code;
public String message;
private String message;
PeakFlowStatusEnum(Integer code, String message) {
this.code = code;
......@@ -28,18 +28,10 @@ public enum PeakFlowStatusEnum {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String toString() {
return "PeakFlowStatusEnum{" +
......
......@@ -29,4 +29,12 @@ public enum RebalanceDimensionEnum {
public String getMessage() {
return message;
}
@Override
public String toString() {
return "RebalanceDimensionEnum{" +
"code=" + code +
", message='" + message + '\'' +
'}';
}
}
\ No newline at end of file
......@@ -43,18 +43,10 @@ public enum TaskStatusEnum {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String toString() {
return "TaskStatusEnum{" +
......@@ -64,9 +56,6 @@ public enum TaskStatusEnum {
}
public static Boolean isFinished(Integer code) {
if (code >= FINISHED.getCode()) {
return true;
}
return false;
return code >= FINISHED.getCode();
}
}
......@@ -45,11 +45,6 @@ public enum TaskStatusReassignEnum {
}
public static Boolean isFinished(Integer code) {
if (SUCCEED.getCode().equals(code)
|| FAILED.getCode().equals(code)
|| CANCELED.getCode().equals(code)) {
return true;
}
return false;
return SUCCEED.getCode().equals(code) || FAILED.getCode().equals(code) || CANCELED.getCode().equals(code);
}
}
\ No newline at end of file
......@@ -33,4 +33,12 @@ public enum TopicAuthorityEnum {
public String getMessage() {
return message;
}
@Override
public String toString() {
return "TopicAuthorityEnum{" +
"code=" + code +
", message='" + message + '\'' +
'}';
}
}
......@@ -29,4 +29,12 @@ public enum TopicExpiredStatusEnum {
public String getMessage() {
return message;
}
@Override
public String toString() {
return "TopicExpiredStatusEnum{" +
"status=" + status +
", message='" + message + '\'' +
'}';
}
}
......@@ -23,18 +23,10 @@ public enum TopicOffsetChangedEnum {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String toString() {
return "TopicOffsetChangedEnum{" +
......
......@@ -5,11 +5,11 @@ package com.xiaojukeji.kafka.manager.common.bizenum.gateway;
* @date 20/7/28
*/
public enum GatewayConfigKeyEnum {
SD_CLUSTER_ID("SERVICE_DISCOVERY_CLUSTER_ID", "SERVICE_DISCOVERY_CLUSTER_ID"),
SD_QUEUE_SIZE("SERVICE_DISCOVERY_QUEUE_SIZE", "SERVICE_DISCOVERY_QUEUE_SIZE"),
SD_APP_ID_RATE("SERVICE_DISCOVERY_APPID_RATE", "SERVICE_DISCOVERY_APPID_RATE"),
SD_IP_RATE("SERVICE_DISCOVERY_IP_RATE", "SERVICE_DISCOVERY_IP_RATE"),
SD_SP_RATE("SERVICE_DISCOVERY_SP_RATE", "SERVICE_DISCOVERY_SP_RATE"),
SD_CLUSTER_ID("SD_CLUSTER_ID", "SD_CLUSTER_ID"),
SD_QUEUE_SIZE("SD_QUEUE_SIZE", "SD_QUEUE_SIZE"),
SD_APP_RATE("SD_APP_RATE", "SD_APP_RATE"),
SD_IP_RATE("SD_IP_RATE", "SD_IP_RATE"),
SD_SP_RATE("SD_SP_RATE", "SD_SP_RATE"),
;
......@@ -26,18 +26,10 @@ public enum GatewayConfigKeyEnum {
return configType;
}
public void setConfigType(String configType) {
this.configType = configType;
}
public String getConfigName() {
return configName;
}
public void setConfigName(String configName) {
this.configName = configName;
}
@Override
public String toString() {
return "GatewayConfigKeyEnum{" +
......
......@@ -12,4 +12,7 @@ public class ApiLevelContent {
public static final int LEVEL_NORMAL_3 = 3;
public static final int LEVEL_DEFAULT_4 = 4;
private ApiLevelContent() {
}
}
\ No newline at end of file
......@@ -28,4 +28,7 @@ public class ApiPrefix {
// gateway
public static final String GATEWAY_API_V1_PREFIX = "/gateway" + API_V1_PREFIX;
private ApiPrefix() {
}
}
\ No newline at end of file
......@@ -30,4 +30,7 @@ public class ConfigConstant {
public static final String BROKER_CAPACITY_LIMIT_CONFIG_KEY = "BROKER_CAPACITY_LIMIT_CONFIG";
public static final String KAFKA_CLUSTER_DO_CONFIG_KEY = "KAFKA_CLUSTER_DO_CONFIG";
private ConfigConstant() {
}
}
......@@ -45,4 +45,7 @@ public class Constant {
public static final Integer DEFAULT_MAX_CAL_TOPIC_EXPIRED_DAY = 90;
public static final Integer INVALID_CODE = -1;
private Constant() {
}
}
......@@ -16,4 +16,7 @@ public class KafkaConstant {
public static final String CLIENT_VERSION_NAME_UNKNOWN = "unknown";
public static final String RETENTION_MS_KEY = "retention.ms";
private KafkaConstant() {
}
}
\ No newline at end of file
......@@ -39,4 +39,7 @@ public class KafkaMetricsCollections {
* Broker信息
*/
public static final int BROKER_VERSION = 400;
private KafkaMetricsCollections() {
}
}
......@@ -10,4 +10,7 @@ public class LogConstant {
public static final String API_METRICS_LOGGER = "API_METRICS_LOGGER";
public static final String SCHEDULED_TASK_LOGGER = "SCHEDULED_TASK_LOGGER";
private LogConstant() {
}
}
\ No newline at end of file
......@@ -11,4 +11,7 @@ public class LoginConstant {
public static final String COOKIE_CHINESE_USERNAME_KEY = "chineseName";
public static final Integer COOKIE_OR_SESSION_MAX_AGE_UNIT_MS = 24 * 60 * 60 * 1000;
private LoginConstant() {
}
}
\ No newline at end of file
......@@ -6,4 +6,7 @@ package com.xiaojukeji.kafka.manager.common.constant;
*/
public class SystemCodeConstant {
public static final String KAFKA_MANAGER = "kafka-manager";
private SystemCodeConstant() {
}
}
\ No newline at end of file
......@@ -54,4 +54,7 @@ public class TopicCreationConstant {
* 单次自动化审批, 最多允许的通过单子
*/
public static final Integer MAX_PASSED_ORDER_NUM_PER_TASK = 200;
private TopicCreationConstant() {
}
}
\ No newline at end of file
......@@ -16,4 +16,7 @@ public class TopicSampleConstant {
public static final Integer MAX_TIMEOUT_UNIT_MS = 10000;
public static final Integer POLL_TIME_OUT_UNIT_MS = 2000;
public static final Integer MAX_DATA_LENGTH_UNIT_BYTE = 2048;
private TopicSampleConstant() {
}
}
\ No newline at end of file
package com.xiaojukeji.kafka.manager.common.constant;
public class TrickLoginConstant {
/**
* HTTP Header key
*/
public static final String TRICK_LOGIN_SWITCH = "Trick-Login-Switch";
public static final String TRICK_LOGIN_USER = "Trick-Login-User";
/**
* 配置允许 trick 登录用户名单
*/
public static final String TRICK_LOGIN_LEGAL_USER_CONFIG_KEY = "SECURITY.TRICK_USERS";
/**
* 开关状态值
*/
public static final String TRICK_LOGIN_SWITCH_ON = "on";
public static final String TRICK_LOGIN_SWITCH_OFF = "off";
private TrickLoginConstant() {
}
}
......@@ -2,6 +2,7 @@ package com.xiaojukeji.kafka.manager.common.utils;
import com.xiaojukeji.kafka.manager.common.constant.Constant;
import com.xiaojukeji.kafka.manager.common.constant.LoginConstant;
import com.xiaojukeji.kafka.manager.common.constant.TrickLoginConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
......@@ -53,13 +54,6 @@ public class SpringTool implements ApplicationContextAware, DisposableBean {
return getApplicationContext().getBeansOfType(type);
}
// /**
// * 从静态变量applicationContext中去的Bean,自动转型为所复制对象的类型
// */
// public static <T> T getBean(Class<T> requiredType) {
// return (T) applicationContext.getBean(requiredType);
// }
/**
* 清除SpringContextHolder中的ApplicationContext为Null
*/
......@@ -87,10 +81,18 @@ public class SpringTool implements ApplicationContextAware, DisposableBean {
}
public static String getUserName(){
HttpServletRequest request =
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpSession session = request.getSession();
String username = (String) session.getAttribute(LoginConstant.SESSION_USERNAME_KEY);
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String username = null;
if (TrickLoginConstant.TRICK_LOGIN_SWITCH_ON.equals(request.getHeader(TrickLoginConstant.TRICK_LOGIN_SWITCH))) {
// trick登录方式的获取用户
username = request.getHeader(TrickLoginConstant.TRICK_LOGIN_USER);
} else {
// 走页面登录方式登录的获取用户
HttpSession session = request.getSession();
username = (String) session.getAttribute(LoginConstant.SESSION_USERNAME_KEY);
}
if (ValidateUtils.isNull(username)) {
return Constant.DEFAULT_USER_NAME;
}
......
......@@ -119,4 +119,7 @@ public class ZkPathUtil {
public static String getControllerCandidatePath(Integer brokerId) {
return D_CONTROLLER_CANDIDATES + ZOOKEEPER_SEPARATOR + brokerId;
}
private ZkPathUtil() {
}
}
......@@ -86,8 +86,8 @@ public class GatewayConfigServiceImpl implements GatewayConfigService {
GatewayConfigDO configDO = null;
try {
configDO = gatewayConfigDao.getByConfigTypeAndName(
GatewayConfigKeyEnum.SD_APP_ID_RATE.getConfigType(),
GatewayConfigKeyEnum.SD_APP_ID_RATE.getConfigName()
GatewayConfigKeyEnum.SD_APP_RATE.getConfigType(),
GatewayConfigKeyEnum.SD_APP_RATE.getConfigName()
);
if (ValidateUtils.isNull(configDO) || configDO.getVersion() <= requestVersion) {
return new AppRateConfig(Long.MIN_VALUE, null);
......
......@@ -91,7 +91,7 @@ public class BrokerServiceImpl implements BrokerService {
for (BrokerDO brokerDO : brokerDOList) {
PeakFlowStatusEnum peakFlowStatus = getPeakFlowStatus(brokerDO.getMaxAvgBytesIn(), peakFlow);
peakFlowStatusMap.put(
peakFlowStatus.code,
peakFlowStatus.getCode(),
peakFlowStatusMap.getOrDefault(peakFlowStatus.getCode(), 0) + 1
);
}
......
......@@ -12,9 +12,29 @@ import javax.servlet.http.HttpServletResponse;
* @date 20/8/20
*/
public interface LoginService {
/**
* 登录
* @param request HttpServletRequest
* @param response HttpServletResponse
* @param dto 登录信息
* @return 登录结果
*/
Result<Account> login(HttpServletRequest request, HttpServletResponse response, LoginDTO dto);
/**
* 登出
* @param request HttpServletRequest
* @param response HttpServletResponse
* @param needJump2LoginPage 是否需要跳转到登录页
*/
void logout(HttpServletRequest request, HttpServletResponse response, Boolean needJump2LoginPage);
/**
* 检查是否登录
* @param request HttpServletRequest
* @param response HttpServletResponse
* @param classRequestMappingValue request-mapping的value
* @return 检查结果, false:未登录或无权限, true:已登录并且有权限
*/
boolean checkLogin(HttpServletRequest request, HttpServletResponse response, String classRequestMappingValue);
}
\ No newline at end of file
......@@ -7,7 +7,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 单点登录抽象类
* 登录抽象类
* @author zengqiao
* @date 20/8/20
*/
......
package com.xiaojukeji.kafka.manager.account.component.login.trick;
import com.xiaojukeji.kafka.manager.common.constant.TrickLoginConstant;
import com.xiaojukeji.kafka.manager.service.service.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.Optional;
/**
* @author zengqiao
* @date 21/5/18
*/
@Service
public class TrickLoginService {
private final static Logger LOGGER = LoggerFactory.getLogger(TrickLoginService.class);
@Autowired
private ConfigService configService;
/**
* 是否开启trick的方式登录
*/
public boolean isTrickLoginOn(HttpServletRequest request) {
return TrickLoginConstant.TRICK_LOGIN_SWITCH_ON.equals(request.getHeader(TrickLoginConstant.TRICK_LOGIN_SWITCH));
}
/**
* 开启trick方式登录后,当前用户是否可以登录
*/
public String checkTrickLogin(HttpServletRequest request) {
String trickLoginUser = request.getHeader(TrickLoginConstant.TRICK_LOGIN_USER);
LOGGER.info("class=TrickLoginService||method=checkTrickLogin||user={}||uri={}||msg=try trick login", trickLoginUser, request.getRequestURI());
if (!checkTrickLogin(trickLoginUser)) {
LOGGER.warn("class=TrickLoginService||method=checkTrickLogin||user={}||uri={}||msg=trick login failed", trickLoginUser, request.getRequestURI());
return null;
}
return trickLoginUser;
}
private boolean checkTrickLogin(String trickLoginUser) {
return Optional.ofNullable(configService.getArrayByKey(TrickLoginConstant.TRICK_LOGIN_LEGAL_USER_CONFIG_KEY, String.class))
.filter(names -> names.contains(trickLoginUser))
.isPresent();
}
}
......@@ -3,6 +3,7 @@ package com.xiaojukeji.kafka.manager.account.impl;
import com.xiaojukeji.kafka.manager.account.AccountService;
import com.xiaojukeji.kafka.manager.account.component.AbstractSingleSignOn;
import com.xiaojukeji.kafka.manager.account.LoginService;
import com.xiaojukeji.kafka.manager.account.component.login.trick.TrickLoginService;
import com.xiaojukeji.kafka.manager.common.bizenum.AccountRoleEnum;
import com.xiaojukeji.kafka.manager.common.constant.ApiPrefix;
import com.xiaojukeji.kafka.manager.common.constant.LoginConstant;
......@@ -31,6 +32,9 @@ public class LoginServiceImpl implements LoginService {
@Autowired
private AccountService accountService;
@Autowired
private TrickLoginService trickLoginService;
@Autowired
private AbstractSingleSignOn singleSignOn;
......@@ -80,7 +84,7 @@ public class LoginServiceImpl implements LoginService {
return true;
}
String username = singleSignOn.checkLoginAndGetLdap(request);
String username = trickLoginService.isTrickLoginOn(request)? trickLoginService.checkTrickLogin(request): singleSignOn.checkLoginAndGetLdap(request);
if (ValidateUtils.isBlank(username)) {
// 未登录, 则返回false, 同时重定向到登录页面
singleSignOn.setRedirectToLoginPage(response);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册