mirror of
https://github.com/didi/KnowStreaming.git
synced 2025-12-24 11:52:08 +08:00
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(应用)如何被使用起来?
|
||||
- 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)
|
||||
|
||||
@@ -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.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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* 单点登录抽象类
|
||||
* 登录抽象类
|
||||
* @author zengqiao
|
||||
* @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.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);
|
||||
|
||||
Reference in New Issue
Block a user