1
0
mirror of synced 2026-05-22 14:43:15 +00:00

refactor: 略微优化 sso 相关 demo

This commit is contained in:
click33
2025-05-03 06:46:31 +08:00
parent 62e5c9b19d
commit ad4e8408fe
15 changed files with 321 additions and 165 deletions
@@ -47,6 +47,9 @@ public class ApiName {
/** SSO-Client端:单点注销地址 */
public String ssoLogout = "/sso/logout";
/** SSO-Client端:判断当前是否登录地址 */
public String ssoIsLogin = "/sso/isLogin";
/** SSO-Client端:单点注销的回调 */
public String ssoLogoutCall = "/sso/logoutCall";
@@ -67,6 +70,7 @@ public class ApiName {
this.ssoSignout = prefix + this.ssoSignout;
this.ssoLogin = prefix + this.ssoLogin;
this.ssoLogout = prefix + this.ssoLogout;
this.ssoIsLogin = prefix + this.ssoIsLogin;
this.ssoPushC = prefix + this.ssoPushC;
this.ssoLogoutCall = prefix + this.ssoLogoutCall;
return this;
@@ -87,6 +91,7 @@ public class ApiName {
this.ssoSignout = this.ssoSignout.replaceFirst(oldPrefix, prefix);
this.ssoLogin = this.ssoLogin.replaceFirst(oldPrefix, prefix);
this.ssoLogout = this.ssoLogout.replaceFirst(oldPrefix, prefix);
this.ssoIsLogin = this.ssoIsLogin.replaceFirst(oldPrefix, prefix);
this.ssoPushC = this.ssoPushC.replaceFirst(oldPrefix, prefix);
this.ssoLogoutCall = this.ssoLogoutCall.replaceFirst(oldPrefix, prefix);
return this;
@@ -41,6 +41,9 @@ public class ParamName {
/** client参数名称 */
public String client = "client";
/** tokenName 参数 */
public String tokenName = "tokenName";
/** tokenValue 参数 */
public String tokenValue = "tokenValue";
@@ -72,4 +75,10 @@ public class ParamName {
/** singleDeviceIdLogout 参数 */
public String singleDeviceIdLogout = "singleDeviceIdLogout";
public String isLogin = "isLogin";
public String authUrl = "authUrl";
public String redirectUrl = "redirectUrl";
public String currSsoLoginUrl = "currSsoLoginUrl";
}
@@ -111,16 +111,17 @@ public class SaSsoClientProcessor {
String back = req.getParam(paramName.back, "/");
String ticket = req.getParam(paramName.ticket);
// 如果当前Client端已经登录,则无需访问SSO认证中心,可以直接返回
if(stpLogic.isLogin()) {
return res.redirect(back);
}
/*
* 此时有两种情况:
* 情况1ticket无值,说明此请求是Client端访问,需要重定向至SSO认证中心
* 情况2:ticket有值,说明此请求从SSO认证中心重定向而来,需要根据ticket进行登录
*/
if(ticket == null) {
// 如果当前Client端已经登录,则无需访问SSO认证中心,可以直接返回
if(stpLogic.isLogin()) {
return res.redirect(back);
}
// 获取当前项目的 sso 登录地址
// 全局配置了就是用全局的,否则使用当前请求的地址
String currSsoLoginUrl;
@@ -31,6 +31,7 @@ import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.parameter.SaLogoutParameter;
import cn.dev33.satoken.util.SaFoxUtil;
import cn.dev33.satoken.util.SaResult;
import cn.dev33.satoken.util.SaSugar;
import java.util.Map;
@@ -113,43 +114,34 @@ public class SaSsoServerProcessor {
String redirect = req.getParam(paramName.redirect);
String client = req.getParam(paramName.client);
// 方式1:直接重定向回Client端 (mode=simple)
if(mode.equals(SaSsoConsts.MODE_SIMPLE)) {
// 若 redirect 为空,则选择 homeRoute,若 homeRoute 也为空,则抛出异常
if(SaFoxUtil.isEmpty(redirect)) {
if(SaFoxUtil.isEmpty(cfg.getHomeRoute())) {
throw new SaSsoException("未指定 redirect 参数,也未配置 homeRoute 路由,无法完成重定向操作").setCode(SaSsoErrorCode.CODE_30014);
}
return res.redirect(cfg.getHomeRoute());
// 若 redirect 为空,则选择 homeRoute,若 homeRoute 也为空,则抛出异常
if(SaFoxUtil.isEmpty(redirect)) {
if(SaFoxUtil.isEmpty(cfg.getHomeRoute())) {
throw new SaSsoException("未指定 redirect 参数,也未配置 homeRoute 路由,无法完成重定向操作").setCode(SaSsoErrorCode.CODE_30014);
}
ssoServerTemplate.checkRedirectUrl(client, redirect);
return res.redirect(redirect);
} else {
// 方式2:带着 ticket 参数重定向回Client端 (mode=ticket)
// 校验提供的client是否为非法字符
// if(SaSsoConsts.CLIENT_WILDCARD.equals(client)) {
// throw new SaSsoException("无效 client 标识:" + client).setCode(SaSsoErrorCode.CODE_30013);
// }
// 若 redirect 为空,则选择 homeRoute,若 homeRoute 也为空,则抛出异常
if(SaFoxUtil.isEmpty(redirect)) {
if(SaFoxUtil.isEmpty(cfg.getHomeRoute())) {
throw new SaSsoException("未指定 redirect 参数,也未配置 homeRoute 路由,无法完成重定向操作").setCode(SaSsoErrorCode.CODE_30014);
}
return res.redirect(cfg.getHomeRoute());
}
// 构建并跳转
String redirectUrl = ssoServerTemplate.buildRedirectUrl(client, redirect, stpLogic.getLoginId(), stpLogic.getTokenValue());
// 构建成功,说明 redirect 地址合法,此时需要更新一下该账号的Session有效期
if(cfg.getAutoRenewTimeout()) {
stpLogic.renewTimeout(stpLogic.getConfigOrGlobal().getTimeout());
}
// 跳转
return res.redirect(redirectUrl);
return res.redirect(cfg.getHomeRoute());
}
String redirectUrl = SaSugar.get(() -> {
// 方式1:直接重定向回Client端 (mode=simple)
if(mode.equals(SaSsoConsts.MODE_SIMPLE)) {
ssoServerTemplate.checkRedirectUrl(client, redirect);
return redirect;
} else {
// 方式2:带着 ticket 参数重定向回Client端 (mode=ticket)
// 构建并跳转
String _redirectUrl = ssoServerTemplate.buildRedirectUrl(client, redirect, stpLogic.getLoginId(), stpLogic.getTokenValue());
// 构建成功,说明 redirect 地址合法,此时需要更新一下该账号的Session有效期
if(cfg.getAutoRenewTimeout()) {
stpLogic.renewTimeout(stpLogic.getConfigOrGlobal().getTimeout());
}
return _redirectUrl;
}
});
// 跳转
return res.redirect(redirectUrl);
}
/**
@@ -99,7 +99,7 @@ public class SaSsoClientTemplate extends SaSsoTemplate {
* 部分 Servlet 版本 request.getRequestURL() 返回的 url 带有 query 参数,形如:http://domain.com?id=1
* 如果不加判断会造成最终生成的 serverAuthUrl 带有双 back 参数 ,这个 if 判断正是为了解决此问题
*/
if( ! clientLoginUrl.contains(paramName.back + "=" + back) ) {
if( ! clientLoginUrl.contains(paramName.back + "=") ) {
clientLoginUrl = SaFoxUtil.joinParam(clientLoginUrl, paramName.back, back);
}