fix: SSO登录退出相关问题
This commit is contained in:
parent
7b0284f38f
commit
14c2d2dd81
|
@ -9,6 +9,7 @@ import org.springframework.stereotype.Controller;
|
|||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.reactive.result.view.Rendering;
|
||||
import org.springframework.web.server.WebSession;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Locale;
|
||||
|
@ -23,7 +24,7 @@ public class SSOController {
|
|||
@MsAuditLog(module = OperLogModule.AUTH_TITLE, type = OperLogConstants.LOGIN, title = "登录")
|
||||
public Rendering callbackWithAuthId(@RequestParam("code") String code, @PathVariable("authId") String authId, WebSession session, Locale locale) throws Exception {
|
||||
ssoService.exchangeToken(code, authId, session, locale);
|
||||
return Rendering.redirectTo("/?_token=" + CodingUtil.base64Encoding(session.getId()))
|
||||
return Rendering.redirectTo("/#/?_token=" + CodingUtil.base64Encoding(session.getId()))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -31,7 +32,7 @@ public class SSOController {
|
|||
@MsAuditLog(module = OperLogModule.AUTH_TITLE, type = OperLogConstants.LOGIN, title = "登录")
|
||||
public Rendering callback(@RequestParam("code") String code, @RequestParam("state") String authId, WebSession session, Locale locale) throws Exception {
|
||||
ssoService.exchangeToken(code, authId, session, locale);
|
||||
return Rendering.redirectTo("/?_token=" + CodingUtil.base64Encoding(session.getId()))
|
||||
return Rendering.redirectTo("/#/?_token=" + CodingUtil.base64Encoding(session.getId()))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -39,28 +40,26 @@ public class SSOController {
|
|||
@MsAuditLog(module = OperLogModule.AUTH_TITLE, type = OperLogConstants.LOGIN, title = "登录")
|
||||
public Rendering casCallback(@RequestParam("ticket") String ticket, @PathVariable("authId") String authId, WebSession session, Locale locale) throws Exception {
|
||||
ssoService.serviceValidate(ticket, authId, session, locale);
|
||||
return Rendering.redirectTo("/?_token=" + CodingUtil.base64Encoding(session.getId()))
|
||||
return Rendering.redirectTo("/#/?_token=" + CodingUtil.base64Encoding(session.getId()))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* oidc 登出 callback
|
||||
*/
|
||||
@PostMapping("/callback/logout")
|
||||
public Rendering logoutCallback(@RequestParam("logout_token") String logoutToken) {
|
||||
ssoService.kickOutUser(logoutToken);
|
||||
return Rendering.redirectTo("/#/login")
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* cas 登出 callback
|
||||
*/
|
||||
@PostMapping("/callback/cas/logout")
|
||||
public Rendering logoutCasCallback(@RequestParam("logoutRequest") String logoutRequest) {
|
||||
ssoService.kickOutCasUser(logoutRequest);
|
||||
return Rendering.redirectTo("/#/login")
|
||||
.build();
|
||||
}
|
||||
// /**
|
||||
// * oidc 登出 callback
|
||||
// */
|
||||
// @PostMapping("/callback/logout")
|
||||
// public Mono<Void> logoutCallback(@RequestParam("logout_token") String logoutToken) {
|
||||
// ssoService.kickOutUser(logoutToken);
|
||||
// return Mono.empty();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * cas 登出 callback
|
||||
// */
|
||||
// @PostMapping("/callback/cas/logout")
|
||||
// public Mono<Void> logoutCasCallback(@RequestParam("logoutRequest") String logoutRequest) {
|
||||
// ssoService.kickOutCasUser(logoutRequest);
|
||||
// return Mono.empty();
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ import java.util.Optional;
|
|||
public class SessionFilter implements WebFilter {
|
||||
// 所有模块的前缀
|
||||
private static final String[] PREFIX = new String[]{"/setting", "/project", "/api", "/performance", "/track", "/workstation", "/ui", "/report"};
|
||||
private static final String[] TO_SUB_SERVICE = new String[]{"/license", "/system", "/resource"};
|
||||
private static final String[] TO_SUB_SERVICE = new String[]{"/license", "/system", "/resource", "/sso/callback/logout", "/sso/callback/cas/logout"};
|
||||
private static final String PERFORMANCE_DOWNLOAD_PREFIX = "/jmeter/";
|
||||
private static final String API_DOWNLOAD_PREFIX = "/api/jmeter/";
|
||||
|
||||
|
|
|
@ -189,6 +189,7 @@ export default {
|
|||
|
||||
activated() {
|
||||
this.initTableData();
|
||||
this.$router.replace({query: null})
|
||||
},
|
||||
methods: {
|
||||
currentUser: () => {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Vue from 'vue';
|
||||
import VueI18n from "vue-i18n";
|
||||
|
||||
Vue.use(VueI18n);
|
||||
|
||||
// 直接加载翻译的语言文件
|
||||
|
@ -45,9 +46,10 @@ const setLang = lang => {
|
|||
}
|
||||
|
||||
export const setLanguage = lang => {
|
||||
if (lang) {
|
||||
lang = lang.replace('_', '-');
|
||||
if (!lang) {
|
||||
return;
|
||||
}
|
||||
lang = lang.replace('_', '-');
|
||||
if (i18n.locale !== lang) {
|
||||
importLanguage(lang).then(setLang);
|
||||
} else {
|
||||
|
|
|
@ -39,9 +39,8 @@ instance.interceptors.request.use(
|
|||
}
|
||||
// sso callback 过来的会有sessionId在url上
|
||||
if (!config.headers['X-AUTH-TOKEN']) {
|
||||
const paramsStr = window.location.search
|
||||
const params = new URLSearchParams(paramsStr)
|
||||
let sessionId = params.get('_token');
|
||||
const paramsStr = window.location.href
|
||||
let sessionId = paramsStr.split('_token=')[1]
|
||||
if (sessionId) {
|
||||
config.headers['X-AUTH-TOKEN'] = Base64.decode(sessionId);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package io.metersphere.controller;
|
||||
|
||||
import io.metersphere.service.SSOLogoutService;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("sso")
|
||||
public class SSOLogoutController {
|
||||
@Resource
|
||||
private SSOLogoutService ssoLogoutService;
|
||||
|
||||
/**
|
||||
* oidc 登出 callback
|
||||
*/
|
||||
@PostMapping("/callback/logout")
|
||||
public void logoutCallback(@RequestParam("logout_token") String logoutToken) {
|
||||
ssoLogoutService.kickOutUser(logoutToken);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* cas 登出 callback
|
||||
*/
|
||||
@PostMapping("/callback/cas/logout")
|
||||
public void logoutCasCallback(@RequestParam("logoutRequest") String logoutRequest) {
|
||||
ssoLogoutService.kickOutCasUser(logoutRequest);
|
||||
}
|
||||
}
|
|
@ -3,9 +3,12 @@ package io.metersphere.service;
|
|||
import io.metersphere.base.domain.AuthSource;
|
||||
import io.metersphere.base.mapper.AuthSourceMapper;
|
||||
import io.metersphere.commons.constants.UserSource;
|
||||
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.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
|
@ -18,6 +21,8 @@ public class SSOLogoutService {
|
|||
private AuthSourceMapper authSourceMapper;
|
||||
@Resource
|
||||
private RestTemplate restTemplate;
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
/**
|
||||
* oidc logout
|
||||
|
@ -35,4 +40,31 @@ public class SSOLogoutService {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void kickOutUser(String logoutToken) {
|
||||
String[] split = StringUtils.split(logoutToken, '.');
|
||||
for (String s : split) {
|
||||
String v = CodingUtil.base64Decoding(s);
|
||||
Map obj = JSON.parseMap(v);
|
||||
String sub = (String) obj.get("sub");
|
||||
if (StringUtils.isNotEmpty(sub)) {
|
||||
SessionUtils.kickOutUser(sub);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void kickOutCasUser(String logoutRequest) {
|
||||
String ticket = StringUtils.substringBetween(logoutRequest, "<samlp:SessionIndex>", "</samlp:SessionIndex>");
|
||||
if (StringUtils.isEmpty(ticket)) {
|
||||
return;
|
||||
}
|
||||
String name = stringRedisTemplate.opsForValue().get(ticket);
|
||||
if (StringUtils.isEmpty(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SessionUtils.kickOutUser(name);
|
||||
stringRedisTemplate.delete(ticket);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue