mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-09-19 10:08:07 +08:00
OAuth2.0模块 beta
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package cn.dev33.satoken.context.model;
|
||||
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
/**
|
||||
@@ -20,7 +21,7 @@ public interface SaRequest {
|
||||
* @param name 键
|
||||
* @return 值
|
||||
*/
|
||||
public String getParameter(String name);
|
||||
public String getParam(String name);
|
||||
|
||||
/**
|
||||
* 在 [请求体] 里获取一个值,值为空时返回默认值
|
||||
@@ -28,14 +29,39 @@ public interface SaRequest {
|
||||
* @param defaultValue 值为空时的默认值
|
||||
* @return 值
|
||||
*/
|
||||
public default String getParameter(String name, String defaultValue) {
|
||||
String value = getParameter(name);
|
||||
public default String getParam(String name, String defaultValue) {
|
||||
String value = getParam(name);
|
||||
if(SaFoxUtil.isEmpty(value)) {
|
||||
return defaultValue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测提供的参数是否为指定值
|
||||
* @param name 键
|
||||
* @param value 值
|
||||
* @return 是否相等
|
||||
*/
|
||||
public default boolean isParam(String name, String value) {
|
||||
String paramValue = getParam(name);
|
||||
return paramValue != null && paramValue.equals(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 [请求体] 里获取一个值 (此值必须存在,否则抛出异常 )
|
||||
* @param name 键
|
||||
* @return 参数值
|
||||
*/
|
||||
public default String getParamNotNull(String name) {
|
||||
String paramValue = getParam(name);
|
||||
if(SaFoxUtil.isEmpty(paramValue)) {
|
||||
throw new SaTokenException("缺少参数:" + name);
|
||||
}
|
||||
return paramValue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 在 [请求头] 里获取一个值
|
||||
* @param name 键
|
||||
|
@@ -30,7 +30,7 @@ public interface SaTokenDao {
|
||||
* 写入Value,并设定存活时间 (单位: 秒)
|
||||
* @param key 键名称
|
||||
* @param value 值
|
||||
* @param timeout 过期时间
|
||||
* @param timeout 过期时间(值>0时限时存储,值=-1时永久存储,值=0或<=-2时不存储)
|
||||
*/
|
||||
public void set(String key, String value, long timeout);
|
||||
|
||||
@@ -75,7 +75,7 @@ public interface SaTokenDao {
|
||||
* 写入Object,并设定存活时间 (单位: 秒)
|
||||
* @param key 键名称
|
||||
* @param object 值
|
||||
* @param timeout 存活时间
|
||||
* @param timeout 存活时间 (值>0时限时存储,值=-1时永久存储,值=0或<=-2时不存储)
|
||||
*/
|
||||
public void setObject(String key, Object object, long timeout);
|
||||
|
||||
|
@@ -45,6 +45,9 @@ public class SaTokenDaoDefaultImpl implements SaTokenDao {
|
||||
|
||||
@Override
|
||||
public void set(String key, String value, long timeout) {
|
||||
if(timeout == 0 || timeout <= SaTokenDao.NOT_VALUE_EXPIRE) {
|
||||
return;
|
||||
}
|
||||
dataMap.put(key, value);
|
||||
expireMap.put(key, (timeout == SaTokenDao.NEVER_EXPIRE) ? (SaTokenDao.NEVER_EXPIRE) : (System.currentTimeMillis() + timeout * 1000));
|
||||
}
|
||||
@@ -84,6 +87,9 @@ public class SaTokenDaoDefaultImpl implements SaTokenDao {
|
||||
|
||||
@Override
|
||||
public void setObject(String key, Object object, long timeout) {
|
||||
if(timeout == 0 || timeout <= SaTokenDao.NOT_VALUE_EXPIRE) {
|
||||
return;
|
||||
}
|
||||
dataMap.put(key, object);
|
||||
expireMap.put(key, (timeout == SaTokenDao.NEVER_EXPIRE) ? (SaTokenDao.NEVER_EXPIRE) : (System.currentTimeMillis() + timeout * 1000));
|
||||
}
|
||||
|
@@ -39,19 +39,19 @@ public class SaSsoHandle {
|
||||
return sso.notLoginView.get();
|
||||
}
|
||||
// 情况2:在SSO认证中心已经登录,开始构建授权重定向地址,下放ticket
|
||||
String redirectUrl = SaSsoUtil.buildRedirectUrl(stpLogic.getLoginId(), req.getParameter(ParamName.redirect));
|
||||
String redirectUrl = SaSsoUtil.buildRedirectUrl(stpLogic.getLoginId(), req.getParam(ParamName.redirect));
|
||||
return res.redirect(redirectUrl);
|
||||
}
|
||||
|
||||
// ---------- SSO-Server端:RestAPI 登录接口
|
||||
if(match(Api.ssoDoLogin)) {
|
||||
return sso.doLoginHandle.apply(req.getParameter("name"), req.getParameter("pwd"));
|
||||
return sso.doLoginHandle.apply(req.getParam("name"), req.getParam("pwd"));
|
||||
}
|
||||
|
||||
// ---------- SSO-Server端:校验ticket 获取账号id
|
||||
if(match(Api.ssoCheckTicket) && sso.isHttp) {
|
||||
String ticket = req.getParameter(ParamName.ticket);
|
||||
String sloCallback = req.getParameter(ParamName.ssoLogoutCall);
|
||||
String ticket = req.getParam(ParamName.ticket);
|
||||
String sloCallback = req.getParam(ParamName.ssoLogoutCall);
|
||||
|
||||
// 校验ticket,获取对应的账号id
|
||||
Object loginId = SaSsoUtil.checkTicket(ticket);
|
||||
@@ -65,8 +65,8 @@ public class SaSsoHandle {
|
||||
|
||||
// ---------- SSO-Server端:单点注销
|
||||
if(match(Api.ssoLogout) && sso.isSlo) {
|
||||
String loginId = req.getParameter(ParamName.loginId);
|
||||
String secretkey = req.getParameter(ParamName.secretkey);
|
||||
String loginId = req.getParam(ParamName.loginId);
|
||||
String secretkey = req.getParam(ParamName.secretkey);
|
||||
|
||||
// 遍历通知Client端注销会话
|
||||
SaSsoUtil.singleLogout(secretkey, loginId, url -> sso.sendHttp.apply(url));
|
||||
@@ -93,8 +93,8 @@ public class SaSsoHandle {
|
||||
|
||||
// ---------- SSO-Client端:登录地址
|
||||
if(match(Api.ssoLogin)) {
|
||||
String back = req.getParameter(ParamName.back, "/");
|
||||
String ticket = req.getParameter(ParamName.ticket);
|
||||
String back = req.getParam(ParamName.back, "/");
|
||||
String ticket = req.getParam(ParamName.ticket);
|
||||
|
||||
// 如果当前Client端已经登录,则无需访问SSO认证中心,可以直接返回
|
||||
if(stpLogic.isLogin()) {
|
||||
@@ -138,10 +138,10 @@ public class SaSsoHandle {
|
||||
// ---------- SSO-Client端:单点注销 [模式二]
|
||||
if(match(Api.ssoLogout) && sso.isSlo && sso.isHttp == false) {
|
||||
stpLogic.logout();
|
||||
if(req.getParameter(ParamName.back) == null) {
|
||||
if(req.getParam(ParamName.back) == null) {
|
||||
return SaResult.ok("单点注销成功");
|
||||
} else {
|
||||
return res.redirect(req.getParameter(ParamName.back, "/"));
|
||||
return res.redirect(req.getParam(ParamName.back, "/"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,10 +155,10 @@ public class SaSsoHandle {
|
||||
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) {
|
||||
if(req.getParam(ParamName.back) == null) {
|
||||
return SaResult.ok("单点注销成功");
|
||||
} else {
|
||||
return res.redirect(req.getParameter(ParamName.back, "/"));
|
||||
return res.redirect(req.getParam(ParamName.back, "/"));
|
||||
}
|
||||
}
|
||||
return SaResult.error("单点注销失败");
|
||||
@@ -166,8 +166,8 @@ public class SaSsoHandle {
|
||||
|
||||
// ---------- SSO-Client端:单点注销的回调 [模式三]
|
||||
if(match(Api.ssoLogoutCall) && sso.isSlo && sso.isHttp) {
|
||||
String loginId = req.getParameter(ParamName.loginId);
|
||||
String secretkey = req.getParameter(ParamName.secretkey);
|
||||
String loginId = req.getParam(ParamName.loginId);
|
||||
String secretkey = req.getParam(ParamName.secretkey);
|
||||
|
||||
SaSsoUtil.checkSecretkey(secretkey);
|
||||
stpLogic.logoutByTokenValue(stpLogic.getTokenValueByLoginId(loginId));
|
||||
|
@@ -132,7 +132,7 @@ public class StpLogic {
|
||||
}
|
||||
// 2. 尝试从请求体里面读取
|
||||
if(tokenValue == null && config.getIsReadBody()){
|
||||
tokenValue = request.getParameter(keyTokenName);
|
||||
tokenValue = request.getParam(keyTokenName);
|
||||
}
|
||||
// 3. 尝试从header里读取
|
||||
if(tokenValue == null && config.getIsReadHead()){
|
||||
|
@@ -204,7 +204,7 @@ public class SaFoxUtil {
|
||||
if(url == null) {
|
||||
url = "";
|
||||
}
|
||||
int index = url.indexOf('?');
|
||||
int index = url.lastIndexOf('?');
|
||||
// ? 不存在
|
||||
if(index == -1) {
|
||||
return url + '?' + parameStr;
|
||||
@@ -236,11 +236,63 @@ public class SaFoxUtil {
|
||||
*/
|
||||
public static String joinParam(String url, String key, Object value) {
|
||||
// 如果参数为空, 直接返回
|
||||
if(isEmpty(url) || isEmpty(key) || isEmpty(String.valueOf(value))) {
|
||||
if(isEmpty(url) || isEmpty(key) || isEmpty(value)) {
|
||||
return url;
|
||||
}
|
||||
return joinParam(url, key + "=" + value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在url上拼接锚参数
|
||||
* @param url url
|
||||
* @param parameStr 参数, 例如 id=1001
|
||||
* @return 拼接后的url字符串
|
||||
*/
|
||||
public static String joinSharpParam(String url, String parameStr) {
|
||||
// 如果参数为空, 直接返回
|
||||
if(parameStr == null || parameStr.length() == 0) {
|
||||
return url;
|
||||
}
|
||||
if(url == null) {
|
||||
url = "";
|
||||
}
|
||||
int index = url.lastIndexOf('#');
|
||||
// ? 不存在
|
||||
if(index == -1) {
|
||||
return url + '#' + parameStr;
|
||||
}
|
||||
// ? 是最后一位
|
||||
if(index == url.length() - 1) {
|
||||
return url + parameStr;
|
||||
}
|
||||
// ? 是其中一位
|
||||
if(index > -1 && index < url.length() - 1) {
|
||||
String separatorChar = "&";
|
||||
// 如果最后一位是 不是&, 且 parameStr 第一位不是 &, 就增送一个 &
|
||||
if(url.lastIndexOf(separatorChar) != url.length() - 1 && parameStr.indexOf(separatorChar) != 0) {
|
||||
return url + separatorChar + parameStr;
|
||||
} else {
|
||||
return url + parameStr;
|
||||
}
|
||||
}
|
||||
// 正常情况下, 代码不可能执行到此
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在url上拼接锚参数
|
||||
* @param url url
|
||||
* @param key 参数名称
|
||||
* @param value 参数值
|
||||
* @return 拼接后的url字符串
|
||||
*/
|
||||
public static String joinSharpParam(String url, String key, Object value) {
|
||||
// 如果参数为空, 直接返回
|
||||
if(isEmpty(url) || isEmpty(key) || isEmpty(value)) {
|
||||
return url;
|
||||
}
|
||||
return joinSharpParam(url, key + "=" + value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数组的所有元素使用逗号拼接在一起
|
||||
|
Reference in New Issue
Block a user