OAuth2.0模块 beta

This commit is contained in:
click33
2021-07-17 23:14:23 +08:00
parent 93e231ff18
commit 742b65366a
29 changed files with 1655 additions and 712 deletions

View File

@@ -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 键

View File

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

View File

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

View File

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

View File

@@ -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()){

View File

@@ -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);
}
/**
* 将数组的所有元素使用逗号拼接在一起