mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-09-19 10:08:07 +08:00
优化单点登录步骤
This commit is contained in:
@@ -14,22 +14,22 @@ public class SaSsoConsts {
|
||||
public static final class Api {
|
||||
|
||||
/** SSO-Server端:授权地址 */
|
||||
public static String ssoAuth = "/ssoAuth";
|
||||
public static String ssoAuth = "/sso/auth";
|
||||
|
||||
/** SSO-Server端:RestAPI 登录接口 */
|
||||
public static String ssoDoLogin = "/ssoDoLogin";
|
||||
public static String ssoDoLogin = "/sso/doLogin";
|
||||
|
||||
/** SSO-Server端:校验ticket 获取账号id */
|
||||
public static String ssoCheckTicket = "/ssoCheckTicket";
|
||||
public static String ssoCheckTicket = "/sso/checkTicket";
|
||||
|
||||
/** SSO-Server端 (and Client端):单点注销 */
|
||||
public static String ssoLogout = "/ssoLogout";
|
||||
public static String ssoLogout = "/sso/logout";
|
||||
|
||||
/** SSO-Client端:登录地址 */
|
||||
public static String ssoLogin = "/ssoLogin";
|
||||
public static String ssoLogin = "/sso/login";
|
||||
|
||||
/** SSO-Client端:单点注销的回调 */
|
||||
public static String ssoLogoutCall = "/ssoLogoutCall";
|
||||
public static String ssoLogoutCall = "/sso/logoutCall";
|
||||
|
||||
}
|
||||
|
||||
|
@@ -8,7 +8,7 @@ import cn.dev33.satoken.context.model.SaResponse;
|
||||
import cn.dev33.satoken.router.SaRouter;
|
||||
import cn.dev33.satoken.sso.SaSsoConsts.Api;
|
||||
import cn.dev33.satoken.sso.SaSsoConsts.ParamName;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.stp.StpLogic;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
|
||||
@@ -29,16 +29,17 @@ public class SaSsoHandle {
|
||||
SaRequest req = SaHolder.getRequest();
|
||||
SaResponse res = SaHolder.getResponse();
|
||||
SaSsoConfig sso = SaManager.getConfig().getSso();
|
||||
StpLogic stpLogic = SaSsoUtil.saSsoTemplate.stpLogic;
|
||||
|
||||
// ---------- SSO-Server端:单点登录授权地址
|
||||
if(match(Api.ssoAuth)) {
|
||||
// ---------- 此处两种情况分开处理:
|
||||
// 情况1:在SSO认证中心尚未登录,则先去登登录
|
||||
if(StpUtil.isLogin() == false) {
|
||||
if(stpLogic.isLogin() == false) {
|
||||
return sso.notLoginView.get();
|
||||
}
|
||||
// 情况2:在SSO认证中心已经登录,开始构建授权重定向地址,下放ticket
|
||||
String redirectUrl = SaSsoUtil.buildRedirectUrl(StpUtil.getLoginId(), req.getParameter(ParamName.redirect));
|
||||
String redirectUrl = SaSsoUtil.buildRedirectUrl(stpLogic.getLoginId(), req.getParameter(ParamName.redirect));
|
||||
return res.redirect(redirectUrl);
|
||||
}
|
||||
|
||||
@@ -88,6 +89,7 @@ public class SaSsoHandle {
|
||||
SaRequest req = SaHolder.getRequest();
|
||||
SaResponse res = SaHolder.getResponse();
|
||||
SaSsoConfig sso = SaManager.getConfig().getSso();
|
||||
StpLogic stpLogic = SaSsoUtil.saSsoTemplate.stpLogic;
|
||||
|
||||
// ---------- SSO-Client端:登录地址
|
||||
if(match(Api.ssoLogin)) {
|
||||
@@ -95,7 +97,7 @@ public class SaSsoHandle {
|
||||
String ticket = req.getParameter(ParamName.ticket);
|
||||
|
||||
// 如果当前Client端已经登录,则无需访问SSO认证中心,可以直接返回
|
||||
if(StpUtil.isLogin()) {
|
||||
if(stpLogic.isLogin()) {
|
||||
return res.redirect(back);
|
||||
}
|
||||
/*
|
||||
@@ -124,7 +126,7 @@ public class SaSsoHandle {
|
||||
}
|
||||
// ------- 2、如果loginId有值,说明ticket有效,进行登录并重定向至back地址
|
||||
if(loginId != null ) {
|
||||
StpUtil.login(loginId);
|
||||
stpLogic.login(loginId);
|
||||
return res.redirect(back);
|
||||
} else {
|
||||
// 如果ticket无效:
|
||||
@@ -135,7 +137,7 @@ public class SaSsoHandle {
|
||||
|
||||
// ---------- SSO-Client端:单点注销 [模式二]
|
||||
if(match(Api.ssoLogout) && sso.isSlo && sso.isHttp == false) {
|
||||
StpUtil.logout();
|
||||
stpLogic.logout();
|
||||
if(req.getParameter(ParamName.back) == null) {
|
||||
return SaResult.ok("单点注销成功");
|
||||
} else {
|
||||
@@ -146,11 +148,11 @@ public class SaSsoHandle {
|
||||
// ---------- SSO-Client端:单点注销 [模式三]
|
||||
if(match(Api.ssoLogout) && sso.isSlo && sso.isHttp) {
|
||||
// 如果未登录,则无需注销
|
||||
if(StpUtil.isLogin() == false) {
|
||||
if(stpLogic.isLogin() == false) {
|
||||
return SaResult.ok();
|
||||
}
|
||||
// 调用SSO-Server认证中心API
|
||||
String url = SaSsoUtil.buildSloUrl(StpUtil.getLoginId());
|
||||
String url = SaSsoUtil.buildSloUrl(stpLogic.getLoginId());
|
||||
String body = String.valueOf(sso.sendHttp.apply(url));
|
||||
if(SaSsoConsts.OK.equals(body)) {
|
||||
if(req.getParameter(ParamName.back) == null) {
|
||||
@@ -168,7 +170,7 @@ public class SaSsoHandle {
|
||||
String secretkey = req.getParameter(ParamName.secretkey);
|
||||
|
||||
SaSsoUtil.checkSecretkey(secretkey);
|
||||
StpUtil.logoutByTokenValue(StpUtil.getTokenValueByLoginId(loginId));
|
||||
stpLogic.logoutByTokenValue(stpLogic.getTokenValueByLoginId(loginId));
|
||||
return SaSsoConsts.OK;
|
||||
}
|
||||
|
||||
|
@@ -9,7 +9,7 @@ import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.config.SaSsoConfig;
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
import cn.dev33.satoken.sso.SaSsoConsts.ParamName;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.stp.StpLogic;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
/**
|
||||
@@ -17,14 +17,19 @@ import cn.dev33.satoken.util.SaFoxUtil;
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public interface SaSsoInterface {
|
||||
public class SaSsoTemplate {
|
||||
|
||||
public StpLogic stpLogic;
|
||||
public SaSsoTemplate(StpLogic stpLogic) {
|
||||
this.stpLogic = stpLogic;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个 Ticket码
|
||||
* @param loginId 账号id
|
||||
* @return 票据
|
||||
*/
|
||||
public default String createTicket(Object loginId) {
|
||||
public String createTicket(Object loginId) {
|
||||
// 随机一个ticket
|
||||
String ticket = randomTicket(loginId);
|
||||
|
||||
@@ -41,7 +46,7 @@ public interface SaSsoInterface {
|
||||
* 删除一个 Ticket码
|
||||
* @param ticket Ticket码
|
||||
*/
|
||||
public default void deleteTicket(String ticket) {
|
||||
public void deleteTicket(String ticket) {
|
||||
Object loginId = getLoginId(ticket);
|
||||
if(loginId != null) {
|
||||
SaManager.getSaTokenDao().delete(splicingKeyTicketToId(ticket));
|
||||
@@ -55,7 +60,7 @@ public interface SaSsoInterface {
|
||||
* @param redirect Client端提供的重定向地址
|
||||
* @return see note
|
||||
*/
|
||||
public default String buildRedirectUrl(Object loginId, String redirect) {
|
||||
public String buildRedirectUrl(Object loginId, String redirect) {
|
||||
// 校验重定向地址
|
||||
checkRedirectUrl(redirect);
|
||||
|
||||
@@ -79,7 +84,7 @@ public interface SaSsoInterface {
|
||||
* @param ticket Ticket码
|
||||
* @return 账号id
|
||||
*/
|
||||
public default Object getLoginId(String ticket) {
|
||||
public Object getLoginId(String ticket) {
|
||||
if(SaFoxUtil.isEmpty(ticket)) {
|
||||
return null;
|
||||
}
|
||||
@@ -93,7 +98,7 @@ public interface SaSsoInterface {
|
||||
* @param cs 要转换的类型
|
||||
* @return 账号id
|
||||
*/
|
||||
public default <T> T getLoginId(String ticket, Class<T> cs) {
|
||||
public <T> T getLoginId(String ticket, Class<T> cs) {
|
||||
return SaFoxUtil.getValueByType(getLoginId(ticket), cs);
|
||||
}
|
||||
|
||||
@@ -102,7 +107,7 @@ public interface SaSsoInterface {
|
||||
* @param ticket Ticket码
|
||||
* @return 账号id
|
||||
*/
|
||||
public default Object checkTicket(String ticket) {
|
||||
public Object checkTicket(String ticket) {
|
||||
Object loginId = getLoginId(ticket);
|
||||
if(loginId != null) {
|
||||
deleteTicket(ticket);
|
||||
@@ -114,7 +119,7 @@ public interface SaSsoInterface {
|
||||
* 校验重定向url合法性
|
||||
* @param url 下放ticket的url地址
|
||||
*/
|
||||
public default void checkRedirectUrl(String url) {
|
||||
public void checkRedirectUrl(String url) {
|
||||
|
||||
// 1、是否是一个有效的url
|
||||
if(SaFoxUtil.isUrl(url) == false) {
|
||||
@@ -144,7 +149,7 @@ public interface SaSsoInterface {
|
||||
* @param back 回调路径
|
||||
* @return [SSO-Server端-认证地址 ]
|
||||
*/
|
||||
public default String buildServerAuthUrl(String clientLoginUrl, String back) {
|
||||
public String buildServerAuthUrl(String clientLoginUrl, String back) {
|
||||
// 服务端认证地址
|
||||
String serverUrl = SaManager.getConfig().getSso().getAuthUrl();
|
||||
|
||||
@@ -165,7 +170,7 @@ public interface SaSsoInterface {
|
||||
* @param url url
|
||||
* @return 编码过后的url
|
||||
*/
|
||||
public default String encodeBackParam(String url) {
|
||||
public String encodeBackParam(String url) {
|
||||
|
||||
// 获取back参数所在位置
|
||||
int index = url.indexOf("?" + ParamName.back + "=");
|
||||
@@ -191,7 +196,7 @@ public interface SaSsoInterface {
|
||||
* @param loginId 账号id
|
||||
* @return 票据
|
||||
*/
|
||||
public default String randomTicket(Object loginId) {
|
||||
public String randomTicket(Object loginId) {
|
||||
return SaFoxUtil.getRandomString(64);
|
||||
}
|
||||
|
||||
@@ -202,7 +207,7 @@ public interface SaSsoInterface {
|
||||
* 校验secretkey秘钥是否有效
|
||||
* @param secretkey 秘钥
|
||||
*/
|
||||
public default void checkSecretkey(String secretkey) {
|
||||
public void checkSecretkey(String secretkey) {
|
||||
if(secretkey == null || secretkey.isEmpty() || secretkey.equals(SaManager.getConfig().getSso().getSecretkey()) == false) {
|
||||
throw new SaTokenException("无效秘钥:" + secretkey);
|
||||
}
|
||||
@@ -214,7 +219,7 @@ public interface SaSsoInterface {
|
||||
* @param ssoLogoutCallUrl 单点注销时的回调URL
|
||||
* @return 构建完毕的URL
|
||||
*/
|
||||
public default String buildCheckTicketUrl(String ticket, String ssoLogoutCallUrl) {
|
||||
public String buildCheckTicketUrl(String ticket, String ssoLogoutCallUrl) {
|
||||
String url = SaManager.getConfig().getSso().getCheckTicketUrl();
|
||||
// 拼接ticket参数
|
||||
url = SaFoxUtil.joinParam(url, ParamName.ticket, ticket);
|
||||
@@ -231,13 +236,13 @@ public interface SaSsoInterface {
|
||||
* @param loginId 账号id
|
||||
* @param sloCallbackUrl 单点注销时的回调URL
|
||||
*/
|
||||
public default void registerSloCallbackUrl(Object loginId, String sloCallbackUrl) {
|
||||
public void registerSloCallbackUrl(Object loginId, String sloCallbackUrl) {
|
||||
if(loginId == null || sloCallbackUrl == null || sloCallbackUrl.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Set<String> urlSet = StpUtil.getSessionByLoginId(loginId).get(SaSsoConsts.SLO_CALLBACK_SET_KEY, ()-> new HashSet<String>());
|
||||
Set<String> urlSet = stpLogic.getSessionByLoginId(loginId).get(SaSsoConsts.SLO_CALLBACK_SET_KEY, ()-> new HashSet<String>());
|
||||
urlSet.add(sloCallbackUrl);
|
||||
StpUtil.getSessionByLoginId(loginId).set(SaSsoConsts.SLO_CALLBACK_SET_KEY, urlSet);
|
||||
stpLogic.getSessionByLoginId(loginId).set(SaSsoConsts.SLO_CALLBACK_SET_KEY, urlSet);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -245,9 +250,9 @@ public interface SaSsoInterface {
|
||||
* @param loginId 账号id
|
||||
* @param fun 调用方法
|
||||
*/
|
||||
public default void forEachSloUrl(Object loginId, CallSloUrlFunction fun) {
|
||||
public void forEachSloUrl(Object loginId, CallSloUrlFunction fun) {
|
||||
String secretkey = SaManager.getConfig().getSso().getSecretkey();
|
||||
Set<String> urlSet = StpUtil.getSessionByLoginId(loginId).get(SaSsoConsts.SLO_CALLBACK_SET_KEY,
|
||||
Set<String> urlSet = stpLogic.getSessionByLoginId(loginId).get(SaSsoConsts.SLO_CALLBACK_SET_KEY,
|
||||
() -> new HashSet<String>());
|
||||
|
||||
for (String url : urlSet) {
|
||||
@@ -264,7 +269,7 @@ public interface SaSsoInterface {
|
||||
* @param loginId 要注销的账号id
|
||||
* @return 单点注销URL
|
||||
*/
|
||||
public default String buildSloUrl(Object loginId) {
|
||||
public String buildSloUrl(Object loginId) {
|
||||
SaSsoConfig ssoConfig = SaManager.getConfig().getSso();
|
||||
String url = ssoConfig.getSloUrl();
|
||||
url = SaFoxUtil.joinParam(url, ParamName.loginId, loginId);
|
||||
@@ -278,7 +283,7 @@ public interface SaSsoInterface {
|
||||
* @param loginId 指定账号
|
||||
* @param fun 调用方法
|
||||
*/
|
||||
public default void singleLogout(String secretkey, Object loginId, CallSloUrlFunction fun) {
|
||||
public void singleLogout(String secretkey, Object loginId, CallSloUrlFunction fun) {
|
||||
// step.1 校验秘钥
|
||||
checkSecretkey(secretkey);
|
||||
|
||||
@@ -287,7 +292,7 @@ public interface SaSsoInterface {
|
||||
|
||||
// step.3 Server端注销
|
||||
// StpUtil.logoutByLoginId(loginId);
|
||||
StpUtil.logoutByTokenValue(StpUtil.getTokenValueByLoginId(loginId));
|
||||
stpLogic.logoutByTokenValue(stpLogic.getTokenValueByLoginId(loginId));
|
||||
}
|
||||
|
||||
|
||||
@@ -299,7 +304,7 @@ public interface SaSsoInterface {
|
||||
* @param ticket
|
||||
* @return key
|
||||
*/
|
||||
public default String splicingKeyTicketToId(String ticket) {
|
||||
public String splicingKeyTicketToId(String ticket) {
|
||||
return SaManager.getConfig().getTokenName() + ":ticket:" + ticket;
|
||||
}
|
||||
|
||||
@@ -308,7 +313,7 @@ public interface SaSsoInterface {
|
||||
* @param id 账号id
|
||||
* @return key
|
||||
*/
|
||||
public default String splicingKeyIdToTicket(Object id) {
|
||||
public String splicingKeyIdToTicket(Object id) {
|
||||
return SaManager.getConfig().getTokenName() + ":id-ticket:" + id;
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package cn.dev33.satoken.sso;
|
||||
|
||||
import cn.dev33.satoken.sso.SaSsoInterface.CallSloUrlFunction;
|
||||
import cn.dev33.satoken.sso.SaSsoTemplate.CallSloUrlFunction;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
|
||||
/**
|
||||
* Sa-Token-SSO 单点登录工具类
|
||||
@@ -10,9 +11,9 @@ import cn.dev33.satoken.sso.SaSsoInterface.CallSloUrlFunction;
|
||||
public class SaSsoUtil {
|
||||
|
||||
/**
|
||||
* 底层 SaSsoServerInterface 对象
|
||||
* 底层 SaSsoTemplate 对象
|
||||
*/
|
||||
public static SaSsoInterface saSsoInterface = new SaSsoInterface() {};
|
||||
public static SaSsoTemplate saSsoTemplate = new SaSsoTemplate(StpUtil.stpLogic);
|
||||
|
||||
/**
|
||||
* 创建一个 Ticket票据
|
||||
@@ -20,7 +21,7 @@ public class SaSsoUtil {
|
||||
* @return 票据
|
||||
*/
|
||||
public static String createTicket(Object loginId) {
|
||||
return saSsoInterface.createTicket(loginId);
|
||||
return saSsoTemplate.createTicket(loginId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -28,7 +29,7 @@ public class SaSsoUtil {
|
||||
* @param ticket Ticket码
|
||||
*/
|
||||
public static void deleteTicket(String ticket) {
|
||||
saSsoInterface.deleteTicket(ticket);
|
||||
saSsoTemplate.deleteTicket(ticket);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,7 +39,7 @@ public class SaSsoUtil {
|
||||
* @return see note
|
||||
*/
|
||||
public static String buildRedirectUrl(Object loginId, String redirect) {
|
||||
return saSsoInterface.buildRedirectUrl(loginId, redirect);
|
||||
return saSsoTemplate.buildRedirectUrl(loginId, redirect);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,7 +48,7 @@ public class SaSsoUtil {
|
||||
* @return 账号id
|
||||
*/
|
||||
public static Object getLoginId(String ticket) {
|
||||
return saSsoInterface.getLoginId(ticket);
|
||||
return saSsoTemplate.getLoginId(ticket);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,7 +59,7 @@ public class SaSsoUtil {
|
||||
* @return 账号id
|
||||
*/
|
||||
public static <T> T getLoginId(String ticket, Class<T> cs) {
|
||||
return saSsoInterface.getLoginId(ticket, cs);
|
||||
return saSsoTemplate.getLoginId(ticket, cs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,7 +68,7 @@ public class SaSsoUtil {
|
||||
* @return 账号id
|
||||
*/
|
||||
public static Object checkTicket(String ticket) {
|
||||
return saSsoInterface.checkTicket(ticket);
|
||||
return saSsoTemplate.checkTicket(ticket);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,7 +76,7 @@ public class SaSsoUtil {
|
||||
* @param url 下放ticket的url地址
|
||||
*/
|
||||
public static void checkAuthUrl(String url) {
|
||||
saSsoInterface.checkRedirectUrl(url);
|
||||
saSsoTemplate.checkRedirectUrl(url);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,7 +86,7 @@ public class SaSsoUtil {
|
||||
* @return [SSO-Server端-认证地址 ]
|
||||
*/
|
||||
public static String buildServerAuthUrl(String clientLoginUrl, String back) {
|
||||
return saSsoInterface.buildServerAuthUrl(clientLoginUrl, back);
|
||||
return saSsoTemplate.buildServerAuthUrl(clientLoginUrl, back);
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +97,7 @@ public class SaSsoUtil {
|
||||
* @param secretkey 秘钥
|
||||
*/
|
||||
public static void checkSecretkey(String secretkey) {
|
||||
saSsoInterface.checkSecretkey(secretkey);
|
||||
saSsoTemplate.checkSecretkey(secretkey);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,7 +107,7 @@ public class SaSsoUtil {
|
||||
* @return 构建完毕的URL
|
||||
*/
|
||||
public static String buildCheckTicketUrl(String ticket, String ssoLogoutCallUrl) {
|
||||
return saSsoInterface.buildCheckTicketUrl(ticket, ssoLogoutCallUrl);
|
||||
return saSsoTemplate.buildCheckTicketUrl(ticket, ssoLogoutCallUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,7 +116,7 @@ public class SaSsoUtil {
|
||||
* @param sloCallbackUrl 单点注销时的回调URL
|
||||
*/
|
||||
public static void registerSloCallbackUrl(Object loginId, String sloCallbackUrl) {
|
||||
saSsoInterface.registerSloCallbackUrl(loginId, sloCallbackUrl);
|
||||
saSsoTemplate.registerSloCallbackUrl(loginId, sloCallbackUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,7 +125,7 @@ public class SaSsoUtil {
|
||||
* @param fun 调用方法
|
||||
*/
|
||||
public static void forEachSloUrl(Object loginId, CallSloUrlFunction fun) {
|
||||
saSsoInterface.forEachSloUrl(loginId, fun);
|
||||
saSsoTemplate.forEachSloUrl(loginId, fun);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,7 +134,7 @@ public class SaSsoUtil {
|
||||
* @return 单点注销URL
|
||||
*/
|
||||
public static String buildSloUrl(Object loginId) {
|
||||
return saSsoInterface.buildSloUrl(loginId);
|
||||
return saSsoTemplate.buildSloUrl(loginId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -143,7 +144,7 @@ public class SaSsoUtil {
|
||||
* @param fun 调用方法
|
||||
*/
|
||||
public static void singleLogout(String secretkey, Object loginId, CallSloUrlFunction fun) {
|
||||
saSsoInterface.singleLogout(secretkey, loginId, fun);
|
||||
saSsoTemplate.singleLogout(secretkey, loginId, fun);
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user