diff --git a/framework/sdk-parent/frontend/src/api/user.js b/framework/sdk-parent/frontend/src/api/user.js index 18fe6cd51e..19bf3f9688 100644 --- a/framework/sdk-parent/frontend/src/api/user.js +++ b/framework/sdk-parent/frontend/src/api/user.js @@ -5,8 +5,8 @@ export function login(url, data) { return post(url, data) } -export function logout() { - return get("/signout") +export function logout(sessionId) { + return sessionId ? get("/signout?X-AUTH-TOKEN=" + sessionId) : get("/signout"); } export function isLogin() { diff --git a/framework/sdk-parent/frontend/src/plugins/request.js b/framework/sdk-parent/frontend/src/plugins/request.js index 5a484dbca3..b0268777a5 100644 --- a/framework/sdk-parent/frontend/src/plugins/request.js +++ b/framework/sdk-parent/frontend/src/plugins/request.js @@ -102,6 +102,12 @@ instance.interceptors.response.use(response => { }, error => { let msg; if (error.response) { + // 判断错误标记 + if (error.response.status === 402) { + if (error.response.headers['redirect']) { + window.open(error.response.headers['redirect']); + } + } checkAuth(error.response); checkPermission(error.response); msg = error.response.data.message || error.response.data; diff --git a/framework/sdk-parent/frontend/src/store/modules/user.js b/framework/sdk-parent/frontend/src/store/modules/user.js index 3d914ea006..6bfe1168a3 100644 --- a/framework/sdk-parent/frontend/src/store/modules/user.js +++ b/framework/sdk-parent/frontend/src/store/modules/user.js @@ -110,9 +110,11 @@ export default { }, userLogout() { + let user = JSON.parse(localStorage.getItem(TokenKey)); + let sessionId = user ? user.sessionId : null; clearSessionStorage(); return new Promise((resolve, reject) => { - logout().then(() => { + logout(sessionId).then(() => { location.href = '/#/login'; location.reload(); resolve(); diff --git a/framework/sdk-parent/sdk/src/main/java/io/metersphere/commons/constants/UserSource.java b/framework/sdk-parent/sdk/src/main/java/io/metersphere/commons/constants/UserSource.java index c4a520d590..1c441cee1b 100644 --- a/framework/sdk-parent/sdk/src/main/java/io/metersphere/commons/constants/UserSource.java +++ b/framework/sdk-parent/sdk/src/main/java/io/metersphere/commons/constants/UserSource.java @@ -1,5 +1,5 @@ package io.metersphere.commons.constants; public enum UserSource { - LOCAL, LDAP, CAS, OIDC + LOCAL, LDAP, CAS, OIDC, OAuth2 } diff --git a/framework/sdk-parent/sdk/src/main/java/io/metersphere/controller/LoginController.java b/framework/sdk-parent/sdk/src/main/java/io/metersphere/controller/LoginController.java index 7acbf986ac..2fb9b6be4e 100644 --- a/framework/sdk-parent/sdk/src/main/java/io/metersphere/controller/LoginController.java +++ b/framework/sdk-parent/sdk/src/main/java/io/metersphere/controller/LoginController.java @@ -2,6 +2,7 @@ package io.metersphere.controller; import io.metersphere.commons.constants.OperLogConstants; import io.metersphere.commons.constants.OperLogModule; +import io.metersphere.commons.constants.SessionConstants; import io.metersphere.commons.constants.UserSource; import io.metersphere.commons.user.SessionUser; import io.metersphere.commons.utils.RsaKey; @@ -26,6 +27,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.util.List; @@ -90,8 +92,8 @@ public class LoginController { @GetMapping(value = "/signout") @MsAuditLog(module = OperLogModule.AUTH_TITLE, beforeEvent = "#msClass.getUserId(id)", type = OperLogConstants.LOGIN, title = "登出", msClass = SessionUtils.class) - public ResultHolder logout() throws Exception { - ssoLogoutService.logout(SecurityUtils.getSubject().getSession()); + public ResultHolder logout(@RequestParam(name = SessionConstants.HEADER_TOKEN, required = false) String sessionId, HttpServletResponse response) throws Exception { + ssoLogoutService.logout(sessionId, response); SecurityUtils.getSubject().logout(); return ResultHolder.success(StringUtils.EMPTY); } diff --git a/framework/sdk-parent/sdk/src/main/java/io/metersphere/service/SSOLogoutService.java b/framework/sdk-parent/sdk/src/main/java/io/metersphere/service/SSOLogoutService.java index d691adbecc..f37d768a88 100644 --- a/framework/sdk-parent/sdk/src/main/java/io/metersphere/service/SSOLogoutService.java +++ b/framework/sdk-parent/sdk/src/main/java/io/metersphere/service/SSOLogoutService.java @@ -7,13 +7,14 @@ import io.metersphere.commons.utils.CodingUtil; import io.metersphere.commons.utils.JSON; import io.metersphere.commons.utils.SessionUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.shiro.SecurityUtils; -import org.apache.shiro.session.Session; +import org.apache.commons.lang3.reflect.MethodUtils; import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.session.data.redis.RedisIndexedSessionRepository; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; import java.util.Map; @Service @@ -25,26 +26,35 @@ public class SSOLogoutService { @Resource private StringRedisTemplate stringRedisTemplate; + @Resource + private RedisIndexedSessionRepository redisIndexedSessionRepository; /** * oidc logout */ - public void logout(Session session) throws Exception { - String authId = (String) SecurityUtils.getSubject().getSession().getAttribute("authId"); + public void logout(String sessionId, HttpServletResponse response) throws Exception { + Object obj = redisIndexedSessionRepository.findById(sessionId); + String authId = (String) MethodUtils.invokeMethod(obj, "getAttribute", "authId"); AuthSource authSource = authSourceMapper.selectByPrimaryKey(authId); if (authSource != null) { Map config = JSON.parseObject(authSource.getConfiguration(), Map.class); if (StringUtils.equals(UserSource.OIDC.name(), authSource.getType())) { - String idToken = (String) SecurityUtils.getSubject().getSession().getAttribute("idToken"); + String idToken = (String) MethodUtils.invokeMethod(obj, "getAttribute", "idToken"); String logoutUrl = (String) config.get("logoutUrl"); - restTemplate.getForEntity(logoutUrl + "?id_token_hint=" + idToken, String.class); } if (StringUtils.equals(UserSource.CAS.name(), authSource.getType())) { - String casTicket = (String) session.getAttribute("casTicket"); + String casTicket = (String) MethodUtils.invokeMethod(obj, "getAttribute", "casTicket"); if (StringUtils.isNotEmpty(casTicket)) { stringRedisTemplate.delete(casTicket); } } + if (StringUtils.equals(UserSource.OAuth2.name(), authSource.getType())) { + if (StringUtils.isNotBlank((String) config.get("logoutUrl"))) { + // 设置标志 + response.setStatus(402); + response.setHeader("redirect", (String) config.get("logoutUrl")); + } + } } } diff --git a/system-setting/frontend/src/business/system/setting/MxAuth.vue b/system-setting/frontend/src/business/system/setting/MxAuth.vue index 0d86abc6ce..75ea623374 100644 --- a/system-setting/frontend/src/business/system/setting/MxAuth.vue +++ b/system-setting/frontend/src/business/system/setting/MxAuth.vue @@ -247,6 +247,13 @@ + + + + + + +