优化单点登录步骤

This commit is contained in:
click33
2021-07-09 02:31:34 +08:00
parent 0a5c5da4b4
commit 936dfe333d
34 changed files with 206 additions and 264 deletions

View File

@@ -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";
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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);
}
}