fix(系统设置): OAuth2登录

This commit is contained in:
shiziyuan9527 2022-11-15 14:59:55 +08:00 committed by 刘瑞斌
parent 0f8a8c06f0
commit 8cc2a53d77
7 changed files with 40 additions and 13 deletions

View File

@ -5,8 +5,8 @@ export function login(url, data) {
return post(url, data) return post(url, data)
} }
export function logout() { export function logout(sessionId) {
return get("/signout") return sessionId ? get("/signout?X-AUTH-TOKEN=" + sessionId) : get("/signout");
} }
export function isLogin() { export function isLogin() {

View File

@ -102,6 +102,12 @@ instance.interceptors.response.use(response => {
}, error => { }, error => {
let msg; let msg;
if (error.response) { if (error.response) {
// 判断错误标记
if (error.response.status === 402) {
if (error.response.headers['redirect']) {
window.open(error.response.headers['redirect']);
}
}
checkAuth(error.response); checkAuth(error.response);
checkPermission(error.response); checkPermission(error.response);
msg = error.response.data.message || error.response.data; msg = error.response.data.message || error.response.data;

View File

@ -110,9 +110,11 @@ export default {
}, },
userLogout() { userLogout() {
let user = JSON.parse(localStorage.getItem(TokenKey));
let sessionId = user ? user.sessionId : null;
clearSessionStorage(); clearSessionStorage();
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
logout().then(() => { logout(sessionId).then(() => {
location.href = '/#/login'; location.href = '/#/login';
location.reload(); location.reload();
resolve(); resolve();

View File

@ -1,5 +1,5 @@
package io.metersphere.commons.constants; package io.metersphere.commons.constants;
public enum UserSource { public enum UserSource {
LOCAL, LDAP, CAS, OIDC LOCAL, LDAP, CAS, OIDC, OAuth2
} }

View File

@ -2,6 +2,7 @@ package io.metersphere.controller;
import io.metersphere.commons.constants.OperLogConstants; import io.metersphere.commons.constants.OperLogConstants;
import io.metersphere.commons.constants.OperLogModule; import io.metersphere.commons.constants.OperLogModule;
import io.metersphere.commons.constants.SessionConstants;
import io.metersphere.commons.constants.UserSource; import io.metersphere.commons.constants.UserSource;
import io.metersphere.commons.user.SessionUser; import io.metersphere.commons.user.SessionUser;
import io.metersphere.commons.utils.RsaKey; import io.metersphere.commons.utils.RsaKey;
@ -26,6 +27,7 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
@ -90,8 +92,8 @@ public class LoginController {
@GetMapping(value = "/signout") @GetMapping(value = "/signout")
@MsAuditLog(module = OperLogModule.AUTH_TITLE, beforeEvent = "#msClass.getUserId(id)", type = OperLogConstants.LOGIN, title = "登出", msClass = SessionUtils.class) @MsAuditLog(module = OperLogModule.AUTH_TITLE, beforeEvent = "#msClass.getUserId(id)", type = OperLogConstants.LOGIN, title = "登出", msClass = SessionUtils.class)
public ResultHolder logout() throws Exception { public ResultHolder logout(@RequestParam(name = SessionConstants.HEADER_TOKEN, required = false) String sessionId, HttpServletResponse response) throws Exception {
ssoLogoutService.logout(SecurityUtils.getSubject().getSession()); ssoLogoutService.logout(sessionId, response);
SecurityUtils.getSubject().logout(); SecurityUtils.getSubject().logout();
return ResultHolder.success(StringUtils.EMPTY); return ResultHolder.success(StringUtils.EMPTY);
} }

View File

@ -7,13 +7,14 @@ import io.metersphere.commons.utils.CodingUtil;
import io.metersphere.commons.utils.JSON; import io.metersphere.commons.utils.JSON;
import io.metersphere.commons.utils.SessionUtils; import io.metersphere.commons.utils.SessionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils; import org.apache.commons.lang3.reflect.MethodUtils;
import org.apache.shiro.session.Session;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.session.data.redis.RedisIndexedSessionRepository;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.Map; import java.util.Map;
@Service @Service
@ -25,26 +26,35 @@ public class SSOLogoutService {
@Resource @Resource
private StringRedisTemplate stringRedisTemplate; private StringRedisTemplate stringRedisTemplate;
@Resource
private RedisIndexedSessionRepository redisIndexedSessionRepository;
/** /**
* oidc logout * oidc logout
*/ */
public void logout(Session session) throws Exception { public void logout(String sessionId, HttpServletResponse response) throws Exception {
String authId = (String) SecurityUtils.getSubject().getSession().getAttribute("authId"); Object obj = redisIndexedSessionRepository.findById(sessionId);
String authId = (String) MethodUtils.invokeMethod(obj, "getAttribute", "authId");
AuthSource authSource = authSourceMapper.selectByPrimaryKey(authId); AuthSource authSource = authSourceMapper.selectByPrimaryKey(authId);
if (authSource != null) { if (authSource != null) {
Map config = JSON.parseObject(authSource.getConfiguration(), Map.class); Map config = JSON.parseObject(authSource.getConfiguration(), Map.class);
if (StringUtils.equals(UserSource.OIDC.name(), authSource.getType())) { 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"); String logoutUrl = (String) config.get("logoutUrl");
restTemplate.getForEntity(logoutUrl + "?id_token_hint=" + idToken, String.class); restTemplate.getForEntity(logoutUrl + "?id_token_hint=" + idToken, String.class);
} }
if (StringUtils.equals(UserSource.CAS.name(), authSource.getType())) { 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)) { if (StringUtils.isNotEmpty(casTicket)) {
stringRedisTemplate.delete(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"));
}
}
} }
} }

View File

@ -247,6 +247,13 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row>
<el-col>
<el-form-item label="Logout Endpoint">
<el-input v-model="form.configuration.logoutUrl"/>
</el-form-item>
</el-col>
</el-row>
</div> </div>
</el-form> </el-form>