From c3a0dbbe485eb23a1f764c5a289461c100b917ea Mon Sep 17 00:00:00 2001 From: zengqiao Date: Tue, 18 May 2021 11:45:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=99=BB=E5=BD=95=E7=BB=95?= =?UTF-8?q?=E8=BF=87=E7=9A=84=E6=8E=A5=E5=8F=A3=E8=B0=83=E7=94=A8=E6=96=B9?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/user_guide/call_api_bypass_login.md | 49 ++++++++++++++++++ docs/user_guide/faq.md | 5 ++ .../common/constant/TrickLoginConstant.java | 21 ++++++++ .../manager/common/utils/SpringTool.java | 24 +++++---- .../kafka/manager/account/LoginService.java | 20 ++++++++ .../component/AbstractSingleSignOn.java | 2 +- .../login/trick/TrickLoginService.java | 50 +++++++++++++++++++ .../account/impl/LoginServiceImpl.java | 6 ++- 8 files changed, 164 insertions(+), 13 deletions(-) create mode 100644 docs/user_guide/call_api_bypass_login.md create mode 100644 kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/constant/TrickLoginConstant.java create mode 100644 kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/login/trick/TrickLoginService.java diff --git a/docs/user_guide/call_api_bypass_login.md b/docs/user_guide/call_api_bypass_login.md new file mode 100644 index 00000000..7a2feac8 --- /dev/null +++ b/docs/user_guide/call_api_bypass_login.md @@ -0,0 +1,49 @@ + +--- + +![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"] +``` + +  + +步骤三:解释说明 + +设置完成上面两步之后,就可以直接调用需要登录的接口了。 + +但是还有一点需要注意,绕过的用户仅能调用他有权限的接口,比如一个普通用户,那么他就只能调用普通的接口,不能去调用运维人员的接口。 + diff --git a/docs/user_guide/faq.md b/docs/user_guide/faq.md index 54ac5543..7fec9050 100644 --- a/docs/user_guide/faq.md +++ b/docs/user_guide/faq.md @@ -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("logi_km" + i,"hello logi_km")); } ``` + +### 18、如何在不登录的情况下,调用一些需要登录的接口? + +具体见:[登录绕过](./call_api_bypass_login.md) diff --git a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/constant/TrickLoginConstant.java b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/constant/TrickLoginConstant.java new file mode 100644 index 00000000..159e1c61 --- /dev/null +++ b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/constant/TrickLoginConstant.java @@ -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"; +} diff --git a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/SpringTool.java b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/SpringTool.java index de0783d2..50723ebf 100644 --- a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/SpringTool.java +++ b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/SpringTool.java @@ -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 getBean(Class 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; } diff --git a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/LoginService.java b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/LoginService.java index 707d4908..48d3f710 100644 --- a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/LoginService.java +++ b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/LoginService.java @@ -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 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 diff --git a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/AbstractSingleSignOn.java b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/AbstractSingleSignOn.java index d6257364..4a67f8f4 100644 --- a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/AbstractSingleSignOn.java +++ b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/AbstractSingleSignOn.java @@ -7,7 +7,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** - * 单点登录抽象类 + * 登录抽象类 * @author zengqiao * @date 20/8/20 */ diff --git a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/login/trick/TrickLoginService.java b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/login/trick/TrickLoginService.java new file mode 100644 index 00000000..08195664 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/login/trick/TrickLoginService.java @@ -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(); + } +} diff --git a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/impl/LoginServiceImpl.java b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/impl/LoginServiceImpl.java index 7a803603..8f079fde 100644 --- a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/impl/LoginServiceImpl.java +++ b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/impl/LoginServiceImpl.java @@ -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);