mirror of
https://github.com/didi/KnowStreaming.git
synced 2025-12-24 11:52:08 +08:00
增加登录绕过的接口调用方式
This commit is contained in:
49
docs/user_guide/call_api_bypass_login.md
Normal file
49
docs/user_guide/call_api_bypass_login.md
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
**一站式`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(应用)如何被使用起来?
|
- 15、APP(应用)如何被使用起来?
|
||||||
- 16、为什么下线应用提示operation forbidden?
|
- 16、为什么下线应用提示operation forbidden?
|
||||||
- 17、删除Topic成功,为什么过一会儿之后又出现了?
|
- 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"));
|
producer.send(new ProducerRecord<String, String>("logi_km" + i,"hello logi_km"));
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 18、如何在不登录的情况下,调用一些需要登录的接口?
|
||||||
|
|
||||||
|
具体见:[登录绕过](./call_api_bypass_login.md)
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
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";
|
||||||
|
}
|
||||||
@@ -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.Constant;
|
||||||
import com.xiaojukeji.kafka.manager.common.constant.LoginConstant;
|
import com.xiaojukeji.kafka.manager.common.constant.LoginConstant;
|
||||||
|
import com.xiaojukeji.kafka.manager.common.constant.TrickLoginConstant;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
@@ -53,13 +54,6 @@ public class SpringTool implements ApplicationContextAware, DisposableBean {
|
|||||||
return getApplicationContext().getBeansOfType(type);
|
return getApplicationContext().getBeansOfType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
|
||||||
// * 从静态变量applicationContext中去的Bean,自动转型为所复制对象的类型
|
|
||||||
// */
|
|
||||||
// public static <T> T getBean(Class<T> requiredType) {
|
|
||||||
// return (T) applicationContext.getBean(requiredType);
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清除SpringContextHolder中的ApplicationContext为Null
|
* 清除SpringContextHolder中的ApplicationContext为Null
|
||||||
*/
|
*/
|
||||||
@@ -87,10 +81,18 @@ public class SpringTool implements ApplicationContextAware, DisposableBean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String getUserName(){
|
public static String getUserName(){
|
||||||
HttpServletRequest request =
|
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||||
((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();
|
HttpSession session = request.getSession();
|
||||||
String username = (String) session.getAttribute(LoginConstant.SESSION_USERNAME_KEY);
|
username = (String) session.getAttribute(LoginConstant.SESSION_USERNAME_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
if (ValidateUtils.isNull(username)) {
|
if (ValidateUtils.isNull(username)) {
|
||||||
return Constant.DEFAULT_USER_NAME;
|
return Constant.DEFAULT_USER_NAME;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,29 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
* @date 20/8/20
|
* @date 20/8/20
|
||||||
*/
|
*/
|
||||||
public interface LoginService {
|
public interface LoginService {
|
||||||
|
/**
|
||||||
|
* 登录
|
||||||
|
* @param request HttpServletRequest
|
||||||
|
* @param response HttpServletResponse
|
||||||
|
* @param dto 登录信息
|
||||||
|
* @return 登录结果
|
||||||
|
*/
|
||||||
Result<Account> login(HttpServletRequest request, HttpServletResponse response, LoginDTO dto);
|
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);
|
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);
|
boolean checkLogin(HttpServletRequest request, HttpServletResponse response, String classRequestMappingValue);
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 单点登录抽象类
|
* 登录抽象类
|
||||||
* @author zengqiao
|
* @author zengqiao
|
||||||
* @date 20/8/20
|
* @date 20/8/20
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
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.AccountService;
|
||||||
import com.xiaojukeji.kafka.manager.account.component.AbstractSingleSignOn;
|
import com.xiaojukeji.kafka.manager.account.component.AbstractSingleSignOn;
|
||||||
import com.xiaojukeji.kafka.manager.account.LoginService;
|
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.bizenum.AccountRoleEnum;
|
||||||
import com.xiaojukeji.kafka.manager.common.constant.ApiPrefix;
|
import com.xiaojukeji.kafka.manager.common.constant.ApiPrefix;
|
||||||
import com.xiaojukeji.kafka.manager.common.constant.LoginConstant;
|
import com.xiaojukeji.kafka.manager.common.constant.LoginConstant;
|
||||||
@@ -31,6 +32,9 @@ public class LoginServiceImpl implements LoginService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private AccountService accountService;
|
private AccountService accountService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TrickLoginService trickLoginService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private AbstractSingleSignOn singleSignOn;
|
private AbstractSingleSignOn singleSignOn;
|
||||||
|
|
||||||
@@ -80,7 +84,7 @@ public class LoginServiceImpl implements LoginService {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
String username = singleSignOn.checkLoginAndGetLdap(request);
|
String username = trickLoginService.isTrickLoginOn(request)? trickLoginService.checkTrickLogin(request): singleSignOn.checkLoginAndGetLdap(request);
|
||||||
if (ValidateUtils.isBlank(username)) {
|
if (ValidateUtils.isBlank(username)) {
|
||||||
// 未登录, 则返回false, 同时重定向到登录页面
|
// 未登录, 则返回false, 同时重定向到登录页面
|
||||||
singleSignOn.setRedirectToLoginPage(response);
|
singleSignOn.setRedirectToLoginPage(response);
|
||||||
|
|||||||
Reference in New Issue
Block a user