mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-04-05 17:37:53 +08:00
完善源码注释
This commit is contained in:
parent
03e38c549a
commit
26ee628b33
@ -3,6 +3,7 @@ package cn.dev33.satoken.action;
|
||||
import java.util.UUID;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.util.SaTokenConsts;
|
||||
import cn.dev33.satoken.util.SaTokenInsideUtil;
|
||||
|
||||
/**
|
||||
@ -21,30 +22,30 @@ public class SaTokenActionDefaultImpl implements SaTokenAction {
|
||||
// 根据配置的tokenStyle生成不同风格的token
|
||||
String tokenStyle = SaTokenManager.getConfig().getTokenStyle();
|
||||
// uuid
|
||||
if("uuid".equals(tokenStyle)) {
|
||||
if(SaTokenConsts.TOKEN_STYLE_UUID.equals(tokenStyle)) {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
// 简单uuid (不带下划线)
|
||||
if("simple-uuid".equals(tokenStyle)) {
|
||||
if(SaTokenConsts.TOKEN_STYLE_SIMPLE_UUID.equals(tokenStyle)) {
|
||||
return UUID.randomUUID().toString().replaceAll("-", "");
|
||||
}
|
||||
// 32位随机字符串
|
||||
if("random-32".equals(tokenStyle)) {
|
||||
if(SaTokenConsts.TOKEN_STYLE_RANDOM_32.equals(tokenStyle)) {
|
||||
return SaTokenInsideUtil.getRandomString(32);
|
||||
}
|
||||
// 64位随机字符串
|
||||
if("random-64".equals(tokenStyle)) {
|
||||
if(SaTokenConsts.TOKEN_STYLE_RANDOM_64.equals(tokenStyle)) {
|
||||
return SaTokenInsideUtil.getRandomString(64);
|
||||
}
|
||||
// 128位随机字符串
|
||||
if("random-128".equals(tokenStyle)) {
|
||||
if(SaTokenConsts.TOKEN_STYLE_RANDOM_128.equals(tokenStyle)) {
|
||||
return SaTokenInsideUtil.getRandomString(128);
|
||||
}
|
||||
// tik风格 (2_14_16)
|
||||
if("tik".equals(tokenStyle)) {
|
||||
if(SaTokenConsts.TOKEN_STYLE_RANDOM_TIK.equals(tokenStyle)) {
|
||||
return SaTokenInsideUtil.getRandomString(2) + "_" + SaTokenInsideUtil.getRandomString(14) + "_" + SaTokenInsideUtil.getRandomString(16) + "__";
|
||||
}
|
||||
// 默认,还是uuid
|
||||
// 默认,还是uuid
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
|
@ -1,220 +1,226 @@
|
||||
package cn.dev33.satoken.config;
|
||||
|
||||
/**
|
||||
* sa-token 配置类 Model
|
||||
* <p> 你可以通过yml、properties、java代码等形式配置本类参数,具体请查阅官方文档
|
||||
* sa-token 配置类 Model
|
||||
* <p>
|
||||
* 你可以通过yml、properties、java代码等形式配置本类参数,具体请查阅官方文档: http://sa-token.dev33.cn/
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaTokenConfig {
|
||||
|
||||
/** token名称 (同时也是cookie名称) */
|
||||
private String tokenName = "satoken";
|
||||
|
||||
private String tokenName = "satoken";
|
||||
|
||||
/** token的长久有效期(单位:秒) 默认30天, -1代表永久 */
|
||||
private long timeout = 30 * 24 * 60 * 60;
|
||||
|
||||
/** token临时有效期 [指定时间内无操作就视为token过期] (单位/秒), 默认-1 代表不限制 (例如可以设置为1800代表30分钟内无操作就过期) */
|
||||
private long activityTimeout = -1;
|
||||
|
||||
/** 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) */
|
||||
private Boolean allowConcurrentLogin = true;
|
||||
|
||||
/** 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) */
|
||||
private Boolean isShare = true;
|
||||
|
||||
private long timeout = 30 * 24 * 60 * 60;
|
||||
|
||||
/**
|
||||
* token临时有效期 [指定时间内无操作就视为token过期] (单位: 秒), 默认-1 代表不限制
|
||||
* (例如可以设置为1800代表30分钟内无操作就过期)
|
||||
*/
|
||||
private long activityTimeout = -1;
|
||||
|
||||
/** 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) */
|
||||
private Boolean allowConcurrentLogin = true;
|
||||
|
||||
/** 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) */
|
||||
private Boolean isShare = true;
|
||||
|
||||
/** 是否尝试从请求体里读取token */
|
||||
private Boolean isReadBody = true;
|
||||
|
||||
private Boolean isReadBody = true;
|
||||
|
||||
/** 是否尝试从header里读取token */
|
||||
private Boolean isReadHead = true;
|
||||
|
||||
private Boolean isReadHead = true;
|
||||
|
||||
/** 是否尝试从cookie里读取token */
|
||||
private Boolean isReadCookie = true;
|
||||
|
||||
private Boolean isReadCookie = true;
|
||||
|
||||
/** token风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) */
|
||||
private String tokenStyle = "uuid";
|
||||
private String tokenStyle = "uuid";
|
||||
|
||||
/** 默认dao层实现类中,每次清理过期数据间隔的时间 (单位: 秒) ,默认值30秒,设置为-1代表不启动定时清理 */
|
||||
private int dataRefreshPeriod = 30;
|
||||
|
||||
|
||||
/** 获取[token专属session]时是否必须登录 (如果配置为true,会在每次获取[token-session]时校验是否登录) */
|
||||
private Boolean tokenSessionCheckLogin = true;
|
||||
|
||||
private Boolean tokenSessionCheckLogin = true;
|
||||
|
||||
/** 是否在初始化配置时打印版本字符画 */
|
||||
private Boolean isV = true;
|
||||
|
||||
|
||||
/**
|
||||
* @return tokenName
|
||||
* @return token名称 (同时也是cookie名称)
|
||||
*/
|
||||
public String getTokenName() {
|
||||
return tokenName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tokenName 要设置的 tokenName
|
||||
* @param tokenName token名称 (同时也是cookie名称)
|
||||
*/
|
||||
public void setTokenName(String tokenName) {
|
||||
this.tokenName = tokenName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return timeout
|
||||
* @return token的长久有效期(单位:秒) 默认30天, -1代表永久
|
||||
*/
|
||||
public long getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param timeout 要设置的 timeout
|
||||
* @param timeout token的长久有效期(单位:秒) 默认30天, -1代表永久
|
||||
*/
|
||||
public void setTimeout(long timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return activityTimeout
|
||||
* @return token临时有效期 [指定时间内无操作就视为token过期] (单位: 秒), 默认-1 代表不限制
|
||||
* (例如可以设置为1800代表30分钟内无操作就过期)
|
||||
*/
|
||||
public long getActivityTimeout() {
|
||||
return activityTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param activityTimeout 要设置的 activityTimeout
|
||||
* @param activityTimeout token临时有效期 [指定时间内无操作就视为token过期] (单位: 秒), 默认-1 代表不限制
|
||||
* (例如可以设置为1800代表30分钟内无操作就过期)
|
||||
*/
|
||||
public void setActivityTimeout(long activityTimeout) {
|
||||
this.activityTimeout = activityTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return allowConcurrentLogin
|
||||
* @return 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
|
||||
*/
|
||||
public Boolean getAllowConcurrentLogin() {
|
||||
return allowConcurrentLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param allowConcurrentLogin 要设置的 allowConcurrentLogin
|
||||
* @param allowConcurrentLogin 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
|
||||
*/
|
||||
public void setAllowConcurrentLogin(Boolean allowConcurrentLogin) {
|
||||
this.allowConcurrentLogin = allowConcurrentLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return isShare
|
||||
* @return 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
|
||||
*/
|
||||
public Boolean getIsShare() {
|
||||
return isShare;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isShare 要设置的 isShare
|
||||
* @param 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
|
||||
*/
|
||||
public void setIsShare(Boolean isShare) {
|
||||
this.isShare = isShare;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return isReadBody
|
||||
* @return 是否尝试从请求体里读取token
|
||||
*/
|
||||
public Boolean getIsReadBody() {
|
||||
return isReadBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isReadBody 要设置的 isReadBody
|
||||
* @param isReadBody 是否尝试从请求体里读取token
|
||||
*/
|
||||
public void setIsReadBody(Boolean isReadBody) {
|
||||
this.isReadBody = isReadBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return isReadHead
|
||||
* @return 是否尝试从header里读取token
|
||||
*/
|
||||
public Boolean getIsReadHead() {
|
||||
return isReadHead;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isReadHead 要设置的 isReadHead
|
||||
* @param 是否尝试从header里读取token
|
||||
*/
|
||||
public void setIsReadHead(Boolean isReadHead) {
|
||||
this.isReadHead = isReadHead;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return isReadCookie
|
||||
* @return 是否尝试从cookie里读取token
|
||||
*/
|
||||
public Boolean getIsReadCookie() {
|
||||
return isReadCookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isReadCookie 要设置的 isReadCookie
|
||||
* @param 是否尝试从cookie里读取token
|
||||
*/
|
||||
public void setIsReadCookie(Boolean isReadCookie) {
|
||||
this.isReadCookie = isReadCookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return tokenStyle
|
||||
* @return token风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)
|
||||
*/
|
||||
public String getTokenStyle() {
|
||||
return tokenStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tokenStyle 要设置的 tokenStyle
|
||||
* @param token风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)
|
||||
*/
|
||||
public void setTokenStyle(String tokenStyle) {
|
||||
this.tokenStyle = tokenStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return dataRefreshPeriod
|
||||
* @return 默认dao层实现类中,每次清理过期数据间隔的时间 (单位: 秒) ,默认值30秒,设置为-1代表不启动定时清理
|
||||
*/
|
||||
public int getDataRefreshPeriod() {
|
||||
return dataRefreshPeriod;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dataRefreshPeriod 要设置的 dataRefreshPeriod
|
||||
* @param dataRefreshPeriod 默认dao层实现类中,每次清理过期数据间隔的时间 (单位: 秒)
|
||||
* ,默认值30秒,设置为-1代表不启动定时清理
|
||||
*/
|
||||
public void setDataRefreshPeriod(int dataRefreshPeriod) {
|
||||
this.dataRefreshPeriod = dataRefreshPeriod;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return tokenSessionCheckLogin
|
||||
* @return 获取[token专属session]时是否必须登录 (如果配置为true,会在每次获取[token-session]时校验是否登录)
|
||||
*/
|
||||
public Boolean getTokenSessionCheckLogin() {
|
||||
return tokenSessionCheckLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tokenSessionCheckLogin 要设置的 tokenSessionCheckLogin
|
||||
* @param tokenSessionCheckLogin 获取[token专属session]时是否必须登录
|
||||
* (如果配置为true,会在每次获取[token-session]时校验是否登录)
|
||||
*/
|
||||
public void setTokenSessionCheckLogin(Boolean tokenSessionCheckLogin) {
|
||||
this.tokenSessionCheckLogin = tokenSessionCheckLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return isV
|
||||
* @return 是否在初始化配置时打印版本字符画
|
||||
*/
|
||||
public Boolean getIsV() {
|
||||
return isV;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isV 要设置的 isV
|
||||
* @param isV 是否在初始化配置时打印版本字符画
|
||||
*/
|
||||
public void setIsV(Boolean isV) {
|
||||
this.isV = isV;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SaTokenConfig [tokenName=" + tokenName + ", timeout=" + timeout + ", activityTimeout=" + activityTimeout
|
||||
@ -224,22 +230,4 @@ public class SaTokenConfig {
|
||||
+ tokenSessionCheckLogin + ", isV=" + isV + "]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -8,44 +8,46 @@ import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* sa-token配置文件创建工厂类
|
||||
* sa-token配置文件的构建工厂类
|
||||
* <p>
|
||||
* 只有在非IOC环境下才会用到此类
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaTokenConfigFactory {
|
||||
|
||||
|
||||
/**
|
||||
* 默认配置文件地址
|
||||
* 配置文件地址
|
||||
*/
|
||||
public static String configPath = "sa-token.properties";
|
||||
|
||||
/**
|
||||
* 根据指定路径获取配置信息
|
||||
* @return 一个SaTokenConfig对象
|
||||
* 根据configPath路径获取配置信息
|
||||
*
|
||||
* @return 一个SaTokenConfig对象
|
||||
*/
|
||||
public static SaTokenConfig createConfig() {
|
||||
Map<String, String> map = readPropToMap(configPath);
|
||||
if(map == null){
|
||||
if (map == null) {
|
||||
// throw new RuntimeException("找不到配置文件:" + configPath, null);
|
||||
}
|
||||
return (SaTokenConfig)initPropByMap(map, new SaTokenConfig());
|
||||
return (SaTokenConfig) initPropByMap(map, new SaTokenConfig());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 将指定路径的properties配置文件读取到Map中
|
||||
* 工具方法: 将指定路径的properties配置文件读取到Map中
|
||||
*
|
||||
* @param propertiesPath 配置文件地址
|
||||
* @return 一个Map
|
||||
*/
|
||||
private static Map<String, String> readPropToMap(String propertiesPath){
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
private static Map<String, String> readPropToMap(String propertiesPath) {
|
||||
Map<String, String> map = new HashMap<String, String>(16);
|
||||
try {
|
||||
InputStream is = SaTokenConfigFactory.class.getClassLoader().getResourceAsStream(propertiesPath);
|
||||
if(is == null){
|
||||
return null;
|
||||
}
|
||||
InputStream is = SaTokenConfigFactory.class.getClassLoader().getResourceAsStream(propertiesPath);
|
||||
if (is == null) {
|
||||
return null;
|
||||
}
|
||||
Properties prop = new Properties();
|
||||
prop.load(is);
|
||||
for (String key : prop.stringPropertyNames()) {
|
||||
@ -55,38 +57,41 @@ public class SaTokenConfigFactory {
|
||||
throw new RuntimeException("配置文件(" + propertiesPath + ")加载失败", e);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将 Map 的值映射到 Model 上
|
||||
* @param map 属性集合
|
||||
* @param obj 对象,或类型
|
||||
* @return 返回实例化后的对象
|
||||
*/
|
||||
private static Object initPropByMap(Map<String, String> map, Object obj){
|
||||
|
||||
if(map == null){
|
||||
map = new HashMap<String, String>();
|
||||
}
|
||||
|
||||
// 1、取出类型
|
||||
Class<?> cs = null;
|
||||
if(obj instanceof Class){ // 如果是一个类型,则将obj=null,以便完成静态属性反射赋值
|
||||
cs = (Class<?>)obj;
|
||||
obj = null;
|
||||
}else{ // 如果是一个对象,则取出其类型
|
||||
cs = obj.getClass();
|
||||
}
|
||||
|
||||
// 2、遍历类型属性,反射赋值
|
||||
for (Field field : cs.getDeclaredFields()) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 工具方法: 将 Map 的值映射到一个 Model 上
|
||||
*
|
||||
* @param map 属性集合
|
||||
* @param obj 对象, 或类型
|
||||
* @return 返回实例化后的对象
|
||||
*/
|
||||
private static Object initPropByMap(Map<String, String> map, Object obj) {
|
||||
|
||||
if (map == null) {
|
||||
map = new HashMap<String, String>(16);
|
||||
}
|
||||
|
||||
// 1、取出类型
|
||||
Class<?> cs = null;
|
||||
if (obj instanceof Class) {
|
||||
// 如果是一个类型,则将obj=null,以便完成静态属性反射赋值
|
||||
cs = (Class<?>) obj;
|
||||
obj = null;
|
||||
} else {
|
||||
// 如果是一个对象,则取出其类型
|
||||
cs = obj.getClass();
|
||||
}
|
||||
|
||||
// 2、遍历类型属性,反射赋值
|
||||
for (Field field : cs.getDeclaredFields()) {
|
||||
String value = map.get(field.getName());
|
||||
if (value == null) {
|
||||
continue; // 如果为空代表没有配置此项
|
||||
// 如果为空代表没有配置此项
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
Object valueConvert = getObjectByClass(value, field.getType()); // 转换值类型
|
||||
Object valueConvert = getObjectByClass(value, field.getType());
|
||||
field.setAccessible(true);
|
||||
field.set(obj, valueConvert);
|
||||
} catch (IllegalArgumentException e) {
|
||||
@ -95,41 +100,39 @@ public class SaTokenConfigFactory {
|
||||
throw new RuntimeException("属性赋值出错:" + field.getName(), e);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字符串转化为指定数据类型
|
||||
* @param str 值
|
||||
* @param cs 要转换的类型
|
||||
* @return 转化好的结果
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T>T getObjectByClass(String str, Class<T> cs){
|
||||
Object value = null;
|
||||
if(str == null){
|
||||
value = null;
|
||||
}else if (cs.equals(String.class)) {
|
||||
value = str;
|
||||
} else if (cs.equals(int.class)||cs.equals(Integer.class)) {
|
||||
value = new Integer(str);
|
||||
} else if (cs.equals(long.class)||cs.equals(Long.class)) {
|
||||
value = new Long(str);
|
||||
} else if (cs.equals(short.class)||cs.equals(Short.class)) {
|
||||
value = new Short(str);
|
||||
} else if (cs.equals(float.class)||cs.equals(Float.class)) {
|
||||
value = new Float(str);
|
||||
} else if (cs.equals(double.class)||cs.equals(Double.class)) {
|
||||
value = new Double(str);
|
||||
} else if (cs.equals(boolean.class)||cs.equals(Boolean.class)) {
|
||||
value = new Boolean(str);
|
||||
}else{
|
||||
throw new RuntimeException("未能将值:" + str + ",转换类型为:" + cs, null);
|
||||
}
|
||||
return (T)value;
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 工具方法: 将字符串转化为指定数据类型
|
||||
*
|
||||
* @param str 值
|
||||
* @param cs 要转换的类型
|
||||
* @return 转化好的结果
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> T getObjectByClass(String str, Class<T> cs) {
|
||||
Object value = null;
|
||||
if (str == null) {
|
||||
value = null;
|
||||
} else if (cs.equals(String.class)) {
|
||||
value = str;
|
||||
} else if (cs.equals(int.class) || cs.equals(Integer.class)) {
|
||||
value = new Integer(str);
|
||||
} else if (cs.equals(long.class) || cs.equals(Long.class)) {
|
||||
value = new Long(str);
|
||||
} else if (cs.equals(short.class) || cs.equals(Short.class)) {
|
||||
value = new Short(str);
|
||||
} else if (cs.equals(float.class) || cs.equals(Float.class)) {
|
||||
value = new Float(str);
|
||||
} else if (cs.equals(double.class) || cs.equals(Double.class)) {
|
||||
value = new Double(str);
|
||||
} else if (cs.equals(boolean.class) || cs.equals(Boolean.class)) {
|
||||
value = new Boolean(str);
|
||||
} else {
|
||||
throw new RuntimeException("未能将值:" + str + ",转换类型为:" + cs, null);
|
||||
}
|
||||
return (T) value;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,7 +5,8 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* sa-token 对cookie的相关操作 接口类
|
||||
* sa-token 对cookie的相关操作 接口类
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
@ -13,36 +14,40 @@ public interface SaTokenCookie {
|
||||
|
||||
/**
|
||||
* 在request对象中获取指定Cookie
|
||||
* @param request request对象
|
||||
* @param cookieName Cookie名称
|
||||
*
|
||||
* @param request request对象
|
||||
* @param cookieName Cookie名称
|
||||
* @return 查找到的Cookie对象
|
||||
*/
|
||||
public Cookie getCookie(HttpServletRequest request, String cookieName);
|
||||
|
||||
/**
|
||||
* 添加Cookie
|
||||
* @param response response对象
|
||||
* @param name Cookie名称
|
||||
* @param value Cookie值
|
||||
* @param path Cookie路径
|
||||
*
|
||||
* @param response response对象
|
||||
* @param name Cookie名称
|
||||
* @param value Cookie值
|
||||
* @param path Cookie路径
|
||||
* @param timeout 过期时间 (秒)
|
||||
*/
|
||||
public void addCookie(HttpServletResponse response, String name, String value, String path, int timeout);
|
||||
|
||||
/**
|
||||
* 删除Cookie
|
||||
* @param request request对象
|
||||
* @param response response对象
|
||||
*
|
||||
* @param request request对象
|
||||
* @param response response对象
|
||||
* @param name Cookie名称
|
||||
*/
|
||||
public void delCookie(HttpServletRequest request, HttpServletResponse response, String name);
|
||||
|
||||
/**
|
||||
* 修改Cookie的value值
|
||||
* @param request request对象
|
||||
*
|
||||
* @param request request对象
|
||||
* @param response response对象
|
||||
* @param name Cookie名称
|
||||
* @param value Cookie值
|
||||
* @param name Cookie名称
|
||||
* @param value Cookie值
|
||||
*/
|
||||
public void updateCookie(HttpServletRequest request, HttpServletResponse response, String name, String value);
|
||||
|
||||
|
@ -5,14 +5,15 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* sa-token 对cookie的相关操作 接口实现类
|
||||
* sa-token 对cookie的相关操作 接口实现类
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaTokenCookieDefaultImpl implements SaTokenCookie {
|
||||
|
||||
/**
|
||||
* 获取指定cookie
|
||||
* 获取指定cookie
|
||||
*/
|
||||
@Override
|
||||
public Cookie getCookie(HttpServletRequest request, String cookieName) {
|
||||
@ -20,7 +21,7 @@ public class SaTokenCookieDefaultImpl implements SaTokenCookie {
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加cookie
|
||||
* 添加cookie
|
||||
*/
|
||||
@Override
|
||||
public void addCookie(HttpServletResponse response, String name, String value, String path, int timeout) {
|
||||
@ -28,7 +29,7 @@ public class SaTokenCookieDefaultImpl implements SaTokenCookie {
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除cookie
|
||||
* 删除cookie
|
||||
*/
|
||||
@Override
|
||||
public void delCookie(HttpServletRequest request, HttpServletResponse response, String name) {
|
||||
@ -36,7 +37,7 @@ public class SaTokenCookieDefaultImpl implements SaTokenCookie {
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改cookie的value值
|
||||
* 修改cookie的value值
|
||||
*/
|
||||
@Override
|
||||
public void updateCookie(HttpServletRequest request, HttpServletResponse response, String name, String value) {
|
||||
|
@ -5,15 +5,17 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Cookie操作工具类
|
||||
* @author kong
|
||||
* Cookie操作工具类
|
||||
*
|
||||
* @author kong
|
||||
*/
|
||||
public class SaTokenCookieUtil {
|
||||
|
||||
/**
|
||||
* 在request对象中获取指定Cookie
|
||||
* @param request request对象
|
||||
* @param cookieName Cookie名称
|
||||
*
|
||||
* @param request request对象
|
||||
* @param cookieName Cookie名称
|
||||
* @return 查找到的Cookie对象
|
||||
*/
|
||||
public static Cookie getCookie(HttpServletRequest request, String cookieName) {
|
||||
@ -30,11 +32,12 @@ public class SaTokenCookieUtil {
|
||||
|
||||
/**
|
||||
* 添加cookie
|
||||
*
|
||||
* @param response response
|
||||
* @param name Cookie名称
|
||||
* @param name Cookie名称
|
||||
* @param value Cookie值
|
||||
* @param path Cookie写入路径
|
||||
* @param timeout Cookie有效期 (秒)
|
||||
* @param timeout Cookie有效期 (秒)
|
||||
*/
|
||||
public static void addCookie(HttpServletResponse response, String name, String value, String path, int timeout) {
|
||||
Cookie cookie = new Cookie(name, value);
|
||||
@ -48,9 +51,10 @@ public class SaTokenCookieUtil {
|
||||
|
||||
/**
|
||||
* 删除Cookie
|
||||
*
|
||||
* @param request request对象
|
||||
* @param response response对象
|
||||
* @param name Cookie名称
|
||||
* @param name Cookie名称
|
||||
*/
|
||||
public static void delCookie(HttpServletRequest request, HttpServletResponse response, String name) {
|
||||
Cookie[] cookies = request.getCookies();
|
||||
@ -66,10 +70,11 @@ public class SaTokenCookieUtil {
|
||||
|
||||
/**
|
||||
* 修改cookie的value值
|
||||
* @param request request对象
|
||||
* @param response response对象
|
||||
* @param name Cookie名称
|
||||
* @param value Cookie值
|
||||
*
|
||||
* @param request request对象
|
||||
* @param response response对象
|
||||
* @param name Cookie名称
|
||||
* @param value Cookie值
|
||||
*/
|
||||
public static void updateCookie(HttpServletRequest request, HttpServletResponse response, String name,
|
||||
String value) {
|
||||
|
@ -22,7 +22,7 @@ public class SaTokenDaoDefaultImpl implements SaTokenDao {
|
||||
|
||||
|
||||
/**
|
||||
* 所有数据集合
|
||||
* 数据集合
|
||||
*/
|
||||
public Map<String, Object> dataMap = new ConcurrentHashMap<String, Object>();
|
||||
|
||||
|
@ -10,7 +10,7 @@ import java.util.List;
|
||||
public class NotLoginException extends RuntimeException {
|
||||
|
||||
/**
|
||||
*
|
||||
* 序列化版本号
|
||||
*/
|
||||
private static final long serialVersionUID = 6806129545290130142L;
|
||||
|
||||
@ -56,6 +56,7 @@ public class NotLoginException extends RuntimeException {
|
||||
* 异常类型
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 获取异常类型
|
||||
* @return 异常类型
|
||||
@ -69,6 +70,7 @@ public class NotLoginException extends RuntimeException {
|
||||
* loginKey
|
||||
*/
|
||||
private String loginKey;
|
||||
|
||||
/**
|
||||
* 获得loginKey
|
||||
* @return loginKey
|
||||
@ -78,8 +80,6 @@ public class NotLoginException extends RuntimeException {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 构造方法创建一个
|
||||
* @param message 异常消息
|
||||
@ -87,7 +87,6 @@ public class NotLoginException extends RuntimeException {
|
||||
* @param type 类型
|
||||
*/
|
||||
public NotLoginException(String message, String loginKey, String type) {
|
||||
// 这里到底要不要拼接上login_key呢?纠结
|
||||
super(message);
|
||||
this.loginKey = loginKey;
|
||||
this.type = type;
|
||||
@ -101,19 +100,19 @@ public class NotLoginException extends RuntimeException {
|
||||
*/
|
||||
public static NotLoginException newInstance(String loginKey, String type) {
|
||||
String message = null;
|
||||
if(type.equals(NOT_TOKEN)) {
|
||||
if(NOT_TOKEN.equals(type)) {
|
||||
message = NOT_TOKEN_MESSAGE;
|
||||
}
|
||||
else if(type.equals(INVALID_TOKEN)) {
|
||||
else if(INVALID_TOKEN.equals(type)) {
|
||||
message = INVALID_TOKEN_MESSAGE;
|
||||
}
|
||||
else if(type.equals(TOKEN_TIMEOUT)) {
|
||||
else if(TOKEN_TIMEOUT.equals(type)) {
|
||||
message = TOKEN_TIMEOUT_MESSAGE;
|
||||
}
|
||||
else if(type.equals(BE_REPLACED)) {
|
||||
else if(BE_REPLACED.equals(type)) {
|
||||
message = BE_REPLACED_MESSAGE;
|
||||
}
|
||||
else if(type.equals(KICK_OUT)) {
|
||||
else if(KICK_OUT.equals(type)) {
|
||||
message = KICK_OUT_MESSAGE;
|
||||
}
|
||||
else {
|
||||
|
@ -4,48 +4,49 @@ import cn.dev33.satoken.stp.StpUtil;
|
||||
|
||||
/**
|
||||
* 没有指定权限码,抛出的异常
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class NotPermissionException extends RuntimeException {
|
||||
|
||||
/**
|
||||
*
|
||||
* 序列化版本号
|
||||
*/
|
||||
private static final long serialVersionUID = 6806129545290130142L;
|
||||
|
||||
|
||||
/** 权限码 */
|
||||
private String code;
|
||||
|
||||
|
||||
/**
|
||||
* @return 获得权限码
|
||||
* @return 获得权限码
|
||||
*/
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* loginKey
|
||||
* loginKey
|
||||
*/
|
||||
private String loginKey;
|
||||
/**
|
||||
* 获得loginKey
|
||||
* @return loginKey
|
||||
|
||||
/**
|
||||
* 获得loginKey
|
||||
*
|
||||
* @return loginKey
|
||||
*/
|
||||
public String getLoginKey() {
|
||||
return loginKey;
|
||||
}
|
||||
|
||||
|
||||
public NotPermissionException(String code) {
|
||||
this(code, StpUtil.stpLogic.loginKey);
|
||||
}
|
||||
public NotPermissionException(String code, String loginKey) {
|
||||
// 这里到底要不要拼接上loginKey呢?纠结
|
||||
super("无此权限:" + code);
|
||||
this.code = code;
|
||||
this.loginKey = loginKey;
|
||||
}
|
||||
this(code, StpUtil.stpLogic.loginKey);
|
||||
}
|
||||
|
||||
public NotPermissionException(String code, String loginKey) {
|
||||
super("无此权限:" + code);
|
||||
this.code = code;
|
||||
this.loginKey = loginKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,48 +4,50 @@ import cn.dev33.satoken.stp.StpUtil;
|
||||
|
||||
/**
|
||||
* 没有指定角色标识,抛出的异常
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class NotRoleException extends RuntimeException {
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* 序列化版本号
|
||||
*/
|
||||
private static final long serialVersionUID = 8243974276159004739L;
|
||||
|
||||
|
||||
/** 角色标识 */
|
||||
private String role;
|
||||
|
||||
|
||||
/**
|
||||
* @return 获得角色标识
|
||||
* @return 获得角色标识
|
||||
*/
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* loginKey
|
||||
* loginKey
|
||||
*/
|
||||
private String loginKey;
|
||||
/**
|
||||
* 获得loginKey
|
||||
* @return loginKey
|
||||
|
||||
/**
|
||||
* 获得loginKey
|
||||
*
|
||||
* @return loginKey
|
||||
*/
|
||||
public String getLoginKey() {
|
||||
return loginKey;
|
||||
}
|
||||
|
||||
|
||||
public NotRoleException(String role) {
|
||||
this(role, StpUtil.stpLogic.loginKey);
|
||||
}
|
||||
this(role, StpUtil.stpLogic.loginKey);
|
||||
}
|
||||
|
||||
public NotRoleException(String role, String loginKey) {
|
||||
// 这里到底要不要拼接上loginKey呢?纠结
|
||||
super("无此角色:" + role);
|
||||
this.role = role;
|
||||
this.loginKey = loginKey;
|
||||
}
|
||||
|
||||
super("无此角色:" + role);
|
||||
this.role = role;
|
||||
this.loginKey = loginKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,33 +1,34 @@
|
||||
package cn.dev33.satoken.exception;
|
||||
|
||||
/**
|
||||
* sa-token框架内部逻辑发生错误抛出的异常
|
||||
* sa-token框架内部逻辑发生错误抛出的异常 (自定义此异常可方便开发者在做全局异常处理时分辨异常类型)
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaTokenException extends RuntimeException {
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* 序列化版本号
|
||||
*/
|
||||
private static final long serialVersionUID = 6806129545290130132L;
|
||||
|
||||
|
||||
/**
|
||||
* 构建一个异常
|
||||
* @param message 异常描述信息
|
||||
* 构建一个异常
|
||||
*
|
||||
* @param message 异常描述信息
|
||||
*/
|
||||
public SaTokenException(String message) {
|
||||
super(message);
|
||||
}
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建一个异常
|
||||
* @param cause 异常对象
|
||||
* 构建一个异常
|
||||
*
|
||||
* @param cause 异常对象
|
||||
*/
|
||||
public SaTokenException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,33 +1,36 @@
|
||||
package cn.dev33.satoken.fun;
|
||||
|
||||
/**
|
||||
* 根据boolean变量,决定是否执行一个函数
|
||||
* 根据boolean变量,决定是否执行一个函数
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class IsRunFunction {
|
||||
|
||||
/**
|
||||
* 变量
|
||||
* 变量
|
||||
*/
|
||||
public Boolean isRun;
|
||||
|
||||
public final Boolean isRun;
|
||||
|
||||
/**
|
||||
* 设定一个变量,如果为true,则执行exe函数
|
||||
* 设定一个变量,如果为true,则执行exe函数
|
||||
*
|
||||
* @param isRun 变量
|
||||
*/
|
||||
public IsRunFunction(boolean isRun) {
|
||||
this.isRun = isRun;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据变量决定是否执行此函数
|
||||
* @param function 函数
|
||||
* 根据变量决定是否执行此函数
|
||||
*
|
||||
* @param function 函数
|
||||
*/
|
||||
public void exe(SaFunction function) {
|
||||
if(isRun) {
|
||||
if (isRun) {
|
||||
function.run();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
package cn.dev33.satoken.fun;
|
||||
|
||||
/**
|
||||
* 模拟身份方法的辅助类
|
||||
* 设定一个函数,方便在Lambda表达式下的函数式编程
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public interface SaFunction {
|
||||
|
||||
/**
|
||||
* 执行的方法
|
||||
* 执行的方法
|
||||
*/
|
||||
public void run();
|
||||
|
||||
|
@ -4,24 +4,25 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Servlet相关操作
|
||||
* Servlet相关操作接口
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public interface SaTokenServlet {
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前请求的 Request 对象
|
||||
* 获取当前请求的 Request 对象
|
||||
*
|
||||
* @return 当前请求的Request对象
|
||||
*/
|
||||
public HttpServletRequest getRequest();
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前请求的 Response 对象
|
||||
* 获取当前请求的 Response 对象
|
||||
*
|
||||
* @return 当前请求的response对象
|
||||
*/
|
||||
public HttpServletResponse getResponse();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -3,28 +3,30 @@ package cn.dev33.satoken.servlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
|
||||
/**
|
||||
* sa-token 对SaTokenServlet接口默认实现类
|
||||
* sa-token 对SaTokenServlet接口默认实现类
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaTokenServletDefaultImpl implements SaTokenServlet {
|
||||
|
||||
/**
|
||||
* 获取当前请求的Request对象
|
||||
* 获取当前请求的Request对象
|
||||
*/
|
||||
@Override
|
||||
public HttpServletRequest getRequest() {
|
||||
throw new RuntimeException("请实现SaTokenServlet接口后进行Servlet相关操作");
|
||||
throw new SaTokenException("请实现SaTokenServlet接口后进行Servlet相关操作");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前请求的Response对象
|
||||
* 获取当前请求的Response对象
|
||||
*/
|
||||
@Override
|
||||
public HttpServletResponse getResponse() {
|
||||
throw new RuntimeException("请实现SaTokenServlet接口后进行Servlet相关操作");
|
||||
throw new SaTokenException("请实现SaTokenServlet接口后进行Servlet相关操作");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -9,213 +9,222 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
|
||||
|
||||
/**
|
||||
* session会话
|
||||
* Session Model
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaSession implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 此会话的id */
|
||||
private String id;
|
||||
|
||||
/** 此会话的创建时间 */
|
||||
|
||||
/** 此Session的id */
|
||||
private String id;
|
||||
|
||||
/** 此Session的创建时间 */
|
||||
private long createTime;
|
||||
|
||||
/** 此会话的所有数据 */
|
||||
|
||||
/** 此Session的所有挂载数据 */
|
||||
private Map<String, Object> dataMap = new ConcurrentHashMap<String, Object>();
|
||||
|
||||
/**
|
||||
* 构建一个 session对象
|
||||
* 构建一个Session对象
|
||||
*/
|
||||
public SaSession() {}
|
||||
|
||||
/**
|
||||
* 构建一个 session对象
|
||||
* @param id session的id
|
||||
*/
|
||||
public SaSession(String id) {
|
||||
this.id = id;
|
||||
this.createTime = System.currentTimeMillis();
|
||||
public SaSession() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取此会话id
|
||||
* @return 此会话的id
|
||||
*/
|
||||
|
||||
/**
|
||||
* 构建一个Session对象
|
||||
*
|
||||
* @param id Session的id
|
||||
*/
|
||||
public SaSession(String id) {
|
||||
this.id = id;
|
||||
this.createTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取此会话id
|
||||
*
|
||||
* @return 此会话的id
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回当前会话创建时间
|
||||
* 返回当前会话创建时间
|
||||
*
|
||||
* @return 时间戳
|
||||
*/
|
||||
public long getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------- tokenSign相关
|
||||
|
||||
// ----------------------- TokenSign相关
|
||||
|
||||
/**
|
||||
* 本session绑定的token签名列表
|
||||
* 此Session绑定的token签名列表
|
||||
*/
|
||||
private List<TokenSign> tokenSignList = new Vector<TokenSign>();
|
||||
|
||||
|
||||
/**
|
||||
* 返回token签名列表
|
||||
* 返回token签名列表的拷贝副本
|
||||
*
|
||||
* @return token签名列表
|
||||
*/
|
||||
public List<TokenSign> getTokenSignList() {
|
||||
return new Vector<>(tokenSignList);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查找一个token签名
|
||||
* @param tokenValue token值
|
||||
* 查找一个token签名
|
||||
*
|
||||
* @param tokenValue token值
|
||||
* @return 查找到的tokenSign
|
||||
*/
|
||||
public TokenSign getTokenSign(String tokenValue) {
|
||||
for (TokenSign tokenSign : getTokenSignList()) {
|
||||
if(tokenSign.getValue().equals(tokenValue)){
|
||||
return tokenSign;
|
||||
}
|
||||
if (tokenSign.getValue().equals(tokenValue)) {
|
||||
return tokenSign;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个token签名
|
||||
*
|
||||
* @param tokenSign token签名
|
||||
*/
|
||||
public void addTokenSign(TokenSign tokenSign) {
|
||||
// 如果已经存在于列表中,则无需再次添加
|
||||
// 如果已经存在于列表中,则无需再次添加
|
||||
for (TokenSign tokenSign2 : getTokenSignList()) {
|
||||
if(tokenSign2.getValue().equals(tokenSign.getValue())){
|
||||
return;
|
||||
}
|
||||
if (tokenSign2.getValue().equals(tokenSign.getValue())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 添加并更新
|
||||
// 添加并更新
|
||||
tokenSignList.add(tokenSign);
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除一个token签名
|
||||
* @param tokenValue token名称
|
||||
*
|
||||
* @param tokenValue token名称
|
||||
*/
|
||||
public void removeTokenSign(String tokenValue) {
|
||||
TokenSign tokenSign = getTokenSign(tokenValue);
|
||||
if(tokenSignList.remove(tokenSign)) {
|
||||
if (tokenSignList.remove(tokenSign)) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// ----------------------- 存取值
|
||||
|
||||
|
||||
// ----------------------- 存取值
|
||||
|
||||
/**
|
||||
* 写入一个值
|
||||
* @param key 名称
|
||||
* @param value 值
|
||||
* 写入一个值
|
||||
*
|
||||
* @param key 名称
|
||||
* @param value 值
|
||||
*/
|
||||
public void setAttribute(String key, Object value) {
|
||||
dataMap.put(key, value);
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 取出一个值
|
||||
* 取出一个值
|
||||
*
|
||||
* @param key 名称
|
||||
* @return 值
|
||||
* @return 值
|
||||
*/
|
||||
public Object getAttribute(String key) {
|
||||
return dataMap.get(key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 取值,并指定取不到值时的默认值
|
||||
* @param key 名称
|
||||
* @param defaultValue 取不到值的时候返回的默认值
|
||||
* 取值,并指定取不到值时的默认值
|
||||
*
|
||||
* @param key 名称
|
||||
* @param defaultValue 取不到值的时候返回的默认值
|
||||
* @return value
|
||||
*/
|
||||
public Object getAttribute(String key, Object defaultValue) {
|
||||
Object value = getAttribute(key);
|
||||
if(value != null) {
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除一个值
|
||||
* 移除一个值
|
||||
*
|
||||
* @param key 要移除的值的名字
|
||||
*/
|
||||
public void removeAttribute(String key) {
|
||||
dataMap.remove(key);
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 清空所有值
|
||||
* 清空所有值
|
||||
*/
|
||||
public void clearAttribute() {
|
||||
dataMap.clear();
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 是否含有指定key
|
||||
* @param key 是否含有指定值
|
||||
* @return 是否含有
|
||||
* 是否含有指定key
|
||||
*
|
||||
* @param key 是否含有指定值
|
||||
* @return 是否含有
|
||||
*/
|
||||
public boolean containsAttribute(String key) {
|
||||
public boolean containsAttribute(String key) {
|
||||
return dataMap.keySet().contains(key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 返回当前session会话所有key
|
||||
* @return 所有值的key列表
|
||||
* 返回当前session会话所有key
|
||||
*
|
||||
* @return 所有值的key列表
|
||||
*/
|
||||
public Set<String> attributeKeys() {
|
||||
return dataMap.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据集合(如果更新map里的值,请调用session.update()方法避免数据过时 )
|
||||
* @return 返回底层储存值的map对象
|
||||
* 获取数据挂载集合(如果更新map里的值,请调用session.update()方法避免产生脏数据 )
|
||||
*
|
||||
* @return 返回底层储存值的map对象
|
||||
*/
|
||||
public Map<String, Object> getDataMap() {
|
||||
return dataMap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ----------------------- 一些操作
|
||||
|
||||
|
||||
// ----------------------- 一些操作
|
||||
|
||||
/**
|
||||
* 将这个session从持久库更新一下
|
||||
* 将这个Session从持久库更新一下
|
||||
*/
|
||||
public void update() {
|
||||
SaTokenManager.getSaTokenDao().updateSession(this);
|
||||
}
|
||||
|
||||
/** 注销会话(注销后,此session会话将不再存储服务器上) */
|
||||
/** 注销会话 (注销后,此session会话将不再存储服务器上) */
|
||||
public void logout() {
|
||||
SaTokenManager.getSaTokenDao().deleteSession(this.id);
|
||||
}
|
||||
|
||||
/** 如果这个token的tokenSign数量为零,则直接注销会话 */
|
||||
/** 当Session上的tokenSign数量为零时,注销会话 */
|
||||
public void logoutByTokenSignCountToZero() {
|
||||
if(tokenSignList.size() == 0) {
|
||||
if (tokenSignList.size() == 0) {
|
||||
logout();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -3,68 +3,71 @@ package cn.dev33.satoken.session;
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
|
||||
/**
|
||||
* 自定义sa-session工具类
|
||||
* 自定义Session工具类
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaSessionCustomUtil {
|
||||
|
||||
/**
|
||||
* 添加上指定前缀,防止恶意伪造session
|
||||
* 添加上指定前缀,防止恶意伪造session
|
||||
*/
|
||||
public static String sessionKey = "custom";
|
||||
|
||||
/**
|
||||
* 组织一下自定义session的id
|
||||
* 组织一下自定义Session的id
|
||||
*
|
||||
* @param sessionId 会话id
|
||||
* @return sessionId
|
||||
*/
|
||||
public static String getSessionKey(String sessionId) {
|
||||
return SaTokenManager.getConfig().getTokenName() + ":" + sessionKey + ":session:" + sessionId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 指定key的session是否存在
|
||||
|
||||
/**
|
||||
* 验证指定key的Session是否存在
|
||||
*
|
||||
* @param sessionId session的id
|
||||
* @return 是否存在
|
||||
* @return 是否存在
|
||||
*/
|
||||
public boolean isExists(String sessionId) {
|
||||
return SaTokenManager.getSaTokenDao().getSession(getSessionKey(sessionId)) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定key的session
|
||||
|
||||
/**
|
||||
* 获取指定key的Session
|
||||
*
|
||||
* @param sessionId key
|
||||
* @param isCreate 如果没有,是否新建并返回
|
||||
* @param isCreate 如果此Session尚未在DB创建,是否新建并返回
|
||||
* @return SaSession
|
||||
*/
|
||||
public static SaSession getSessionById(String sessionId, boolean isCreate) {
|
||||
SaSession session = SaTokenManager.getSaTokenDao().getSession(getSessionKey(sessionId));
|
||||
if(session == null && isCreate) {
|
||||
if (session == null && isCreate) {
|
||||
session = new SaSession(getSessionKey(sessionId));
|
||||
SaTokenManager.getSaTokenDao().saveSession(session, SaTokenManager.getConfig().getTimeout());
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定key的session, 如果没有则新建并返回
|
||||
|
||||
/**
|
||||
* 获取指定key的Session, 如果此Session尚未在DB创建,则新建并返回
|
||||
*
|
||||
* @param sessionId key
|
||||
* @return session对象
|
||||
* @return session对象
|
||||
*/
|
||||
public static SaSession getSessionById(String sessionId) {
|
||||
return getSessionById(sessionId, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定key的session
|
||||
* @param sessionId 删除指定key
|
||||
/**
|
||||
* 删除指定key的session
|
||||
*
|
||||
* @param sessionId 指定key
|
||||
*/
|
||||
public static void deleteSessionById(String sessionId) {
|
||||
SaTokenManager.getSaTokenDao().deleteSession(getSessionKey(sessionId));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -3,66 +3,62 @@ package cn.dev33.satoken.session;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 挂在到SaSession上的token签名
|
||||
* token签名 Model
|
||||
*
|
||||
* 挂在到SaSession上的token签名
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class TokenSign implements Serializable {
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1406115065849845073L;
|
||||
|
||||
/**
|
||||
* token值
|
||||
* token值
|
||||
*/
|
||||
private String value;
|
||||
|
||||
|
||||
/**
|
||||
* 所在设备标识
|
||||
* 所在设备标识
|
||||
*/
|
||||
private String device;
|
||||
|
||||
|
||||
/** 构建一个 */
|
||||
public TokenSign() {}
|
||||
|
||||
/**
|
||||
* 构建一个
|
||||
* @param value token值
|
||||
* @param device 所在设备标识
|
||||
*/
|
||||
public TokenSign(String value, String device) {
|
||||
this.value = value;
|
||||
this.device = device;
|
||||
public TokenSign() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return value
|
||||
* 构建一个
|
||||
*
|
||||
* @param value token值
|
||||
* @param device 所在设备标识
|
||||
*/
|
||||
public TokenSign(String value, String device) {
|
||||
this.value = value;
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return token value
|
||||
*/
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return device
|
||||
* @return token登录设备
|
||||
*/
|
||||
public String getDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TokenSign [value=" + value + ", device=" + device + "]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
package cn.dev33.satoken.stp;
|
||||
|
||||
/**
|
||||
* 用来描述一个token常用信息的类
|
||||
* token信息Model: 用来描述一个token的常用参数
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
@ -13,177 +14,173 @@ public class SaTokenInfo {
|
||||
/** token值 */
|
||||
public String tokenValue;
|
||||
|
||||
/** 当前是否已经登录 */
|
||||
/** 此token是否已经登录 */
|
||||
public Boolean isLogin;
|
||||
|
||||
/** 当前loginId,未登录时为null */
|
||||
/** 此token对应的LoginId,未登录时为null */
|
||||
public Object loginId;
|
||||
|
||||
/** 当前loginKey */
|
||||
/** LoginKey账号体系标识 */
|
||||
public String loginKey;
|
||||
|
||||
/** token剩余有效期 (单位: 秒) */
|
||||
public long tokenTimeout;
|
||||
|
||||
/** session剩余有效时间 (单位: 秒) */
|
||||
/** User-Session剩余有效时间 (单位: 秒) */
|
||||
public long sessionTimeout;
|
||||
|
||||
/** token专属session剩余有效时间 (单位: 秒) */
|
||||
/** Token-Session剩余有效时间 (单位: 秒) */
|
||||
public long tokenSessionTimeout;
|
||||
|
||||
/**
|
||||
* token剩余无操作有效时间
|
||||
*/
|
||||
|
||||
/** token剩余无操作有效时间 (单位: 秒) */
|
||||
public long tokenActivityTimeout;
|
||||
|
||||
/** 当前登录设备 */
|
||||
/** 登录设备标识 */
|
||||
public String loginDevice;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return tokenName
|
||||
* @return token名称
|
||||
*/
|
||||
public String getTokenName() {
|
||||
return tokenName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tokenName 要设置的 tokenName
|
||||
* @param tokenName token名称
|
||||
*/
|
||||
public void setTokenName(String tokenName) {
|
||||
this.tokenName = tokenName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return tokenValue
|
||||
* @return token值
|
||||
*/
|
||||
public String getTokenValue() {
|
||||
return tokenValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tokenValue 要设置的 tokenValue
|
||||
* @param tokenValue token值
|
||||
*/
|
||||
public void setTokenValue(String tokenValue) {
|
||||
this.tokenValue = tokenValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return isLogin
|
||||
* @return 此token是否已经登录
|
||||
*/
|
||||
public Boolean getIsLogin() {
|
||||
return isLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isLogin 要设置的 isLogin
|
||||
* @param isLogin 此token是否已经登录
|
||||
*/
|
||||
public void setIsLogin(Boolean isLogin) {
|
||||
this.isLogin = isLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return loginId
|
||||
* @return 此token对应的LoginId,未登录时为null
|
||||
*/
|
||||
public Object getLoginId() {
|
||||
return loginId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param loginId 要设置的 loginId
|
||||
* @param loginId 此token对应的LoginId,未登录时为null
|
||||
*/
|
||||
public void setLoginId(Object loginId) {
|
||||
this.loginId = loginId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return loginKey
|
||||
* @return LoginKey账号体系标识
|
||||
*/
|
||||
public String getLoginKey() {
|
||||
return loginKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param loginKey 要设置的 loginKey
|
||||
* @param loginKey LoginKey账号体系标识
|
||||
*/
|
||||
public void setLoginKey(String loginKey) {
|
||||
this.loginKey = loginKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return tokenTimeout
|
||||
* @return token剩余有效期 (单位: 秒)
|
||||
*/
|
||||
public long getTokenTimeout() {
|
||||
return tokenTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tokenTimeout 要设置的 tokenTimeout
|
||||
* @param tokenTimeout token剩余有效期 (单位: 秒)
|
||||
*/
|
||||
public void setTokenTimeout(long tokenTimeout) {
|
||||
this.tokenTimeout = tokenTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return sessionTimeout
|
||||
* @return User-Session剩余有效时间 (单位: 秒)
|
||||
*/
|
||||
public long getSessionTimeout() {
|
||||
return sessionTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sessionTimeout 要设置的 sessionTimeout
|
||||
* @param sessionTimeout User-Session剩余有效时间 (单位: 秒)
|
||||
*/
|
||||
public void setSessionTimeout(long sessionTimeout) {
|
||||
this.sessionTimeout = sessionTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return tokenSessionTimeout
|
||||
* @return Token-Session剩余有效时间 (单位: 秒)
|
||||
*/
|
||||
public long getTokenSessionTimeout() {
|
||||
return tokenSessionTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tokenSessionTimeout 要设置的 tokenSessionTimeout
|
||||
* @param tokenSessionTimeout Token-Session剩余有效时间 (单位: 秒)
|
||||
*/
|
||||
public void setTokenSessionTimeout(long tokenSessionTimeout) {
|
||||
this.tokenSessionTimeout = tokenSessionTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return tokenActivityTimeout
|
||||
* @return token剩余无操作有效时间 (单位: 秒)
|
||||
*/
|
||||
public long getTokenActivityTimeout() {
|
||||
return tokenActivityTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tokenActivityTimeout 要设置的 tokenActivityTimeout
|
||||
* @param tokenActivityTimeout token剩余无操作有效时间 (单位: 秒)
|
||||
*/
|
||||
public void setTokenActivityTimeout(long tokenActivityTimeout) {
|
||||
this.tokenActivityTimeout = tokenActivityTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return loginDevice
|
||||
* @return 登录设备标识
|
||||
*/
|
||||
public String getLoginDevice() {
|
||||
return loginDevice;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param loginDevice 要设置的 loginDevice
|
||||
* @param loginDevice 登录设备标识
|
||||
*/
|
||||
public void setLoginDevice(String loginDevice) {
|
||||
this.loginDevice = loginDevice;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* toString
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SaTokenInfo [tokenName=" + tokenName + ", tokenValue=" + tokenValue + ", isLogin=" + isLogin
|
||||
@ -191,18 +188,5 @@ public class SaTokenInfo {
|
||||
+ ", sessionTimeout=" + sessionTimeout + ", tokenSessionTimeout=" + tokenSessionTimeout
|
||||
+ ", tokenActivityTimeout=" + tokenActivityTimeout + ", loginDevice=" + loginDevice + "]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -3,26 +3,28 @@ package cn.dev33.satoken.stp;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 开放权限验证接口,方便重写
|
||||
* 权限认证接口,实现此接口即可集成权限认证功能
|
||||
*
|
||||
* @author kong
|
||||
*/
|
||||
public interface StpInterface {
|
||||
|
||||
|
||||
/**
|
||||
* 返回指定loginId所拥有的权限码集合
|
||||
* @param loginId 账号id
|
||||
* @param loginKey 具体的stp标识
|
||||
* @return 该账号id具有的权限码集合
|
||||
* 返回指定 LoginId 所拥有的权限码集合
|
||||
*
|
||||
* @param loginId 账号id
|
||||
* @param loginKey 账号体系标识
|
||||
* @return 该账号id具有的权限码集合
|
||||
*/
|
||||
public List<String> getPermissionList(Object loginId, String loginKey);
|
||||
|
||||
/**
|
||||
* 返回指定loginId所拥有的角色标识集合
|
||||
* @param loginId 账号id
|
||||
* @param loginKey 具体的stp标识
|
||||
* @return 该账号id具有的角色标识集合
|
||||
*
|
||||
* @param loginId 账号id
|
||||
* @param loginKey 账号体系标识
|
||||
* @return 该账号id具有的角色标识集合
|
||||
*/
|
||||
public List<String> getRoleList(Object loginId, String loginKey);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,10 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 对StpInterface接口默认的实现类
|
||||
* 对StpInterface接口默认的实现类
|
||||
* <p>
|
||||
* 如果开发者没有实现StpInterface接口,则使用此默认实现
|
||||
*
|
||||
* @author kong
|
||||
*/
|
||||
public class StpInterfaceDefaultImpl implements StpInterface {
|
||||
|
@ -38,15 +38,15 @@ public class StpLogic {
|
||||
public String loginKey = "";
|
||||
|
||||
/**
|
||||
* 初始化StpLogic, 并制定loginKey
|
||||
* @param loginKey 账号标识
|
||||
* 初始化StpLogic, 并指定LoginKey
|
||||
* @param loginKey 账号体系标识
|
||||
*/
|
||||
public StpLogic(String loginKey) {
|
||||
this.loginKey = loginKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前StpLogin的loginKey
|
||||
* 获取当前StpLogin的LoginKey
|
||||
* @return 当前StpLogin的loginKey
|
||||
*/
|
||||
public String getLoginKey(){
|
||||
@ -54,7 +54,7 @@ public class StpLogic {
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入当前StpLogin的loginKey
|
||||
* 写入当前StpLogin的LoginKey
|
||||
* @param loginKey loginKey
|
||||
* @return 对象自身
|
||||
*/
|
||||
@ -75,17 +75,16 @@ public class StpLogic {
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机生成一个tokenValue
|
||||
* 创建一个tokenValue
|
||||
* @param loginId loginId
|
||||
* @return 生成的tokenValue
|
||||
*/
|
||||
public String createTokenValue(Object loginId) {
|
||||
// 去除掉所有逗号
|
||||
return SaTokenManager.getSaTokenAction().createToken(loginId, loginKey).replaceAll(",", "");
|
||||
return SaTokenManager.getSaTokenAction().createToken(loginId, loginKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前tokenValue
|
||||
* 获取当前tokenValue
|
||||
* @return 当前tokenValue
|
||||
*/
|
||||
public String getTokenValue(){
|
||||
@ -100,15 +99,15 @@ public class StpLogic {
|
||||
tokenValue = String.valueOf(request.getAttribute(getKeyJustCreatedSave()));
|
||||
}
|
||||
// 2. 尝试从请求体里面读取
|
||||
if(tokenValue == null && config.getIsReadBody() == true){
|
||||
if(tokenValue == null && config.getIsReadBody()){
|
||||
tokenValue = request.getParameter(keyTokenName);
|
||||
}
|
||||
// 3. 尝试从header里读取
|
||||
if(tokenValue == null && config.getIsReadHead() == true){
|
||||
if(tokenValue == null && config.getIsReadHead()){
|
||||
tokenValue = request.getHeader(keyTokenName);
|
||||
}
|
||||
// 4. 尝试从cookie里读取
|
||||
if(tokenValue == null && config.getIsReadCookie() == true){
|
||||
if(tokenValue == null && config.getIsReadCookie()){
|
||||
Cookie cookie = SaTokenManager.getSaTokenCookie().getCookie(request, keyTokenName);
|
||||
if(cookie != null){
|
||||
tokenValue = cookie.getValue();
|
||||
@ -156,7 +155,6 @@ public class StpLogic {
|
||||
*/
|
||||
public void setLoginId(Object loginId, String device) {
|
||||
|
||||
|
||||
// ------ 1、获取相应对象
|
||||
HttpServletRequest request = SaTokenManager.getSaTokenServlet().getRequest();
|
||||
SaTokenConfig config = getConfig();
|
||||
@ -166,7 +164,7 @@ public class StpLogic {
|
||||
String tokenValue = null;
|
||||
// --- 如果允许并发登录
|
||||
if(config.getAllowConcurrentLogin() == true) {
|
||||
// 如果配置为共享token, 则尝试从session签名记录里取出token
|
||||
// 如果配置为共享token, 则尝试从Session签名记录里取出token
|
||||
if(config.getIsShare() == true) {
|
||||
tokenValue = getTokenValueByLoginId(loginId, device);
|
||||
}
|
||||
@ -178,19 +176,22 @@ public class StpLogic {
|
||||
List<TokenSign> tokenSignList = session.getTokenSignList();
|
||||
for (TokenSign tokenSign : tokenSignList) {
|
||||
if(tokenSign.getDevice().equals(device)) {
|
||||
dao.updateValue(getKeyTokenValue(tokenSign.getValue()), NotLoginException.BE_REPLACED); // 1. 将此token 标记为已顶替
|
||||
clearLastActivity(tokenSign.getValue()); // 2. 清理掉[token-最后操作时间]
|
||||
session.removeTokenSign(tokenSign.getValue()); // 3. 清理账号session上的token签名记录
|
||||
// 1. 将此token 标记为已顶替
|
||||
dao.updateValue(getKeyTokenValue(tokenSign.getValue()), NotLoginException.BE_REPLACED);
|
||||
// 2. 清理掉[token-最后操作时间]
|
||||
clearLastActivity(tokenSign.getValue());
|
||||
// 3. 清理账号session上的token签名记录
|
||||
session.removeTokenSign(tokenSign.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 如果至此,仍未成功创建tokenValue
|
||||
// 如果至此,仍未成功创建tokenValue, 则开始生成一个
|
||||
if(tokenValue == null) {
|
||||
tokenValue = createTokenValue(loginId);
|
||||
}
|
||||
|
||||
// ------ 3. 获取[id-session] (如果还没有创建session, 则新建, 如果已经创建,则续期)
|
||||
// ------ 3. 获取[User-Session] (如果还没有创建session, 则新建, 如果已经创建,则续期)
|
||||
SaSession session = getSessionByLoginId(loginId, false);
|
||||
if(session == null) {
|
||||
session = getSessionByLoginId(loginId);
|
||||
@ -201,10 +202,14 @@ public class StpLogic {
|
||||
session.addTokenSign(new TokenSign(tokenValue, device));
|
||||
|
||||
// ------ 4. 持久化其它数据
|
||||
dao.setValue(getKeyTokenValue(tokenValue), String.valueOf(loginId), config.getTimeout()); // token -> uid
|
||||
request.setAttribute(getKeyJustCreatedSave(), tokenValue); // 将token保存到本次request里
|
||||
setLastActivityToNow(tokenValue); // 写入 [最后操作时间]
|
||||
if(config.getIsReadCookie() == true){ // cookie注入
|
||||
// token -> uid
|
||||
dao.setValue(getKeyTokenValue(tokenValue), String.valueOf(loginId), config.getTimeout());
|
||||
// 将token保存到本次request里
|
||||
request.setAttribute(getKeyJustCreatedSave(), tokenValue);
|
||||
// 写入 [最后操作时间]
|
||||
setLastActivityToNow(tokenValue);
|
||||
// cookie注入
|
||||
if(config.getIsReadCookie() == true){
|
||||
SaTokenManager.getSaTokenCookie().addCookie(SaTokenManager.getSaTokenServlet().getResponse(), getTokenName(), tokenValue, "/", (int)config.getTimeout());
|
||||
}
|
||||
}
|
||||
@ -240,14 +245,14 @@ public class StpLogic {
|
||||
}
|
||||
SaTokenManager.getSaTokenDao().deleteKey(getKeyTokenValue(tokenValue));
|
||||
|
||||
// 2. 尝试清理账号session上的token签名 (如果为null或已被标记为异常, 那么无需继续执行 )
|
||||
// 3. 尝试清理账号session上的token签名 (如果为null或已被标记为异常, 那么无需继续执行 )
|
||||
SaSession session = getSessionByLoginId(loginId, false);
|
||||
if(session == null) {
|
||||
return;
|
||||
}
|
||||
session.removeTokenSign(tokenValue);
|
||||
|
||||
// 3. 尝试注销session
|
||||
// 4. 尝试注销session
|
||||
session.logoutByTokenSignCountToZero();
|
||||
}
|
||||
|
||||
@ -267,13 +272,13 @@ public class StpLogic {
|
||||
* @param device 设备标识 (填null代表所有注销设备)
|
||||
*/
|
||||
public void logoutByLoginId(Object loginId, String device) {
|
||||
// 先获取这个账号的[id-session], 如果为null,则不执行任何操作
|
||||
// 1. 先获取这个账号的[id-session], 如果为null,则不执行任何操作
|
||||
SaSession session = getSessionByLoginId(loginId);
|
||||
if(session == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 循环token签名列表,开始删除相关信息
|
||||
// 2. 循环token签名列表,开始删除相关信息
|
||||
List<TokenSign> tokenSignList = session.getTokenSignList();
|
||||
for (TokenSign tokenSign : tokenSignList) {
|
||||
if(device == null || tokenSign.getDevice().equals(device)) {
|
||||
@ -282,12 +287,12 @@ public class StpLogic {
|
||||
// 2. 清理掉[token-最后操作时间]
|
||||
clearLastActivity(tokenValue);
|
||||
// 3. 标记:已被踢下线
|
||||
SaTokenManager.getSaTokenDao().updateValue(getKeyTokenValue(tokenValue), NotLoginException.KICK_OUT); // 标记:已被踢下线
|
||||
SaTokenManager.getSaTokenDao().updateValue(getKeyTokenValue(tokenValue), NotLoginException.KICK_OUT);
|
||||
// 4. 清理账号session上的token签名
|
||||
session.removeTokenSign(tokenValue);
|
||||
}
|
||||
}
|
||||
// 尝试注销session
|
||||
// 3. 尝试注销session
|
||||
session.logoutByTokenSignCountToZero();
|
||||
}
|
||||
|
||||
@ -314,16 +319,16 @@ public class StpLogic {
|
||||
* @return 账号id
|
||||
*/
|
||||
public Object getLoginId() {
|
||||
// 如果正在[临时身份切换]
|
||||
// 如果正在[临时身份切换], 则返回临时身份
|
||||
if(isSwitch()) {
|
||||
return getSwitchLoginId();
|
||||
}
|
||||
// 如果获取不到token,则抛出:无token
|
||||
// 如果获取不到token,则抛出: 无token
|
||||
String tokenValue = getTokenValue();
|
||||
if(tokenValue == null) {
|
||||
throw NotLoginException.newInstance(loginKey, NotLoginException.NOT_TOKEN);
|
||||
}
|
||||
// 查找此token对应loginId, 则抛出:无效token
|
||||
// 查找此token对应loginId, 如果找不到则抛出:无效token
|
||||
String loginId = getLoginIdNotHandle(tokenValue);
|
||||
if(loginId == null) {
|
||||
throw NotLoginException.newInstance(loginKey, NotLoginException.INVALID_TOKEN);
|
||||
@ -336,14 +341,14 @@ public class StpLogic {
|
||||
if(loginId.equals(NotLoginException.BE_REPLACED)) {
|
||||
throw NotLoginException.newInstance(loginKey, NotLoginException.BE_REPLACED);
|
||||
}
|
||||
// 如果是已经被踢下线了, 则抛出:已被踢下线
|
||||
// 如果是已经被踢下线了, 则抛出:已被踢下线
|
||||
if(loginId.equals(NotLoginException.KICK_OUT)) {
|
||||
throw NotLoginException.newInstance(loginKey, NotLoginException.KICK_OUT);
|
||||
}
|
||||
// 检查是否已经 [临时过期],同时更新[最后操作时间]
|
||||
checkActivityTimeout(tokenValue);
|
||||
updateLastActivityToNow(tokenValue);
|
||||
// 至此,返回loginId
|
||||
// 至此,返回loginId
|
||||
return loginId;
|
||||
}
|
||||
|
||||
@ -387,7 +392,7 @@ public class StpLogic {
|
||||
if(tokenValue == null) {
|
||||
return null;
|
||||
}
|
||||
// loginId为null或者在异常项里面,均视为未登录
|
||||
// loginId为null或者在异常项里面,均视为未登录, 返回null
|
||||
Object loginId = getLoginIdNotHandle(tokenValue);
|
||||
if(loginId == null || NotLoginException.ABNORMAL_LIST.contains(loginId)) {
|
||||
return null;
|
||||
@ -413,10 +418,6 @@ public class StpLogic {
|
||||
* @return 账号id
|
||||
*/
|
||||
public int getLoginIdAsInt() {
|
||||
// Object loginId = getLoginId();
|
||||
// if(loginId instanceof Integer) {
|
||||
// return (Integer)loginId;
|
||||
// }
|
||||
return Integer.valueOf(String.valueOf(getLoginId()));
|
||||
}
|
||||
|
||||
@ -425,10 +426,6 @@ public class StpLogic {
|
||||
* @return 账号id
|
||||
*/
|
||||
public long getLoginIdAsLong() {
|
||||
// Object loginId = getLoginId();
|
||||
// if(loginId instanceof Long) {
|
||||
// return (Long)loginId;
|
||||
// }
|
||||
return Long.valueOf(String.valueOf(getLoginId()));
|
||||
}
|
||||
|
||||
@ -553,11 +550,14 @@ public class StpLogic {
|
||||
// 如果配置忽略token登录校验,则必须保证token不为null (token为null的时候随机创建一个)
|
||||
String tokenValue = getTokenValue();
|
||||
if(tokenValue == null || Objects.equals(tokenValue, "")) {
|
||||
// 随机一个token送给ta
|
||||
// 随机一个token送给Ta
|
||||
tokenValue = createTokenValue(null);
|
||||
// Request做上标记
|
||||
SaTokenManager.getSaTokenServlet().getRequest().setAttribute(getKeyJustCreatedSave(), tokenValue);
|
||||
setLastActivityToNow(tokenValue); // 写入 [最后操作时间]
|
||||
if(getConfig().getIsReadCookie() == true){ // cookie注入
|
||||
// 写入 [最后操作时间]
|
||||
setLastActivityToNow(tokenValue);
|
||||
// cookie注入
|
||||
if(getConfig().getIsReadCookie() == true){
|
||||
SaTokenManager.getSaTokenCookie().addCookie(SaTokenManager.getSaTokenServlet().getResponse(), getTokenName(), tokenValue, "/", (int)getConfig().getTimeout());
|
||||
}
|
||||
}
|
||||
@ -801,7 +801,7 @@ public class StpLogic {
|
||||
List<String> roleList = SaTokenManager.getStpInterface().getRoleList(loginId, loginKey);
|
||||
for (String role : roleArray) {
|
||||
if(roleList.contains(role) == false) {
|
||||
throw new NotRoleException(role, this.loginKey); // 没有权限抛出异常
|
||||
throw new NotRoleException(role, this.loginKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -815,11 +815,12 @@ public class StpLogic {
|
||||
List<String> roleList = SaTokenManager.getStpInterface().getRoleList(loginId, loginKey);
|
||||
for (String role : roleArray) {
|
||||
if(roleList.contains(role) == true) {
|
||||
return; // 有的话提前退出
|
||||
// 有的话提前退出
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(roleArray.length > 0) {
|
||||
throw new NotRoleException(roleArray[0], this.loginKey); // 没有权限抛出异常
|
||||
throw new NotRoleException(roleArray[0], this.loginKey);
|
||||
}
|
||||
}
|
||||
|
||||
@ -865,7 +866,7 @@ public class StpLogic {
|
||||
List<String> permissionList = SaTokenManager.getStpInterface().getPermissionList(loginId, loginKey);
|
||||
for (String permission : permissionArray) {
|
||||
if(permissionList.contains(permission) == false) {
|
||||
throw new NotPermissionException(permission, this.loginKey); // 没有权限抛出异常
|
||||
throw new NotPermissionException(permission, this.loginKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -879,11 +880,12 @@ public class StpLogic {
|
||||
List<String> permissionList = SaTokenManager.getStpInterface().getPermissionList(loginId, loginKey);
|
||||
for (String permission : permissionArray) {
|
||||
if(permissionList.contains(permission) == true) {
|
||||
return; // 有的话提前退出
|
||||
// 有的话提前退出
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(permissionArray.length > 0) {
|
||||
throw new NotPermissionException(permissionArray[0], this.loginKey); // 没有权限抛出异常
|
||||
throw new NotPermissionException(permissionArray[0], this.loginKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ public class StpUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前tokenValue
|
||||
* 获取当前tokenValue
|
||||
* @return 当前tokenValue
|
||||
*/
|
||||
public static String getTokenValue() {
|
||||
|
@ -51,6 +51,9 @@ public class SaTaskUtil {
|
||||
* @author kong
|
||||
*/
|
||||
public static interface FunctionRunClass{
|
||||
/**
|
||||
* 要执行的方法
|
||||
*/
|
||||
public void run();
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,15 @@
|
||||
package cn.dev33.satoken.util;
|
||||
|
||||
/**
|
||||
* 定义sa-token的所有常量
|
||||
* sa-token常量类
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaTokenConsts {
|
||||
|
||||
|
||||
// =================== sa-token版本信息 ===================
|
||||
|
||||
/**
|
||||
* sa-token 版本号
|
||||
*/
|
||||
@ -16,29 +19,62 @@ public class SaTokenConsts {
|
||||
* sa-token 开源地址
|
||||
*/
|
||||
public static final String GITHUB_URL = "https://github.com/click33/sa-token";
|
||||
|
||||
|
||||
// =================== 常量key标记 ===================
|
||||
|
||||
/**
|
||||
* 如果token为本次请求新创建的,则以此字符串为key存储在当前request中
|
||||
* 常量key标记: 如果token为本次请求新创建的,则以此字符串为key存储在当前request中
|
||||
*/
|
||||
public static final String JUST_CREATED_SAVE_KEY = "JUST_CREATED_SAVE_KEY_";
|
||||
|
||||
/**
|
||||
* 如果本次请求已经验证过[无操作过期], 则以此值存储在当前request中 TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY
|
||||
* 常量key标记: 如果本次请求已经验证过[无操作过期], 则以此值存储在当前request中
|
||||
*/
|
||||
public static final String TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY = "TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY_";
|
||||
|
||||
/**
|
||||
* 在登录时,默认使用的设备名称
|
||||
* 常量key标记: 在登录时,默认使用的设备名称
|
||||
*/
|
||||
public static final String DEFAULT_LOGIN_DEVICE = "default-device";
|
||||
|
||||
/**
|
||||
* 在进行临时身份切换时使用的key
|
||||
* 常量key标记: 在进行临时身份切换时使用的key
|
||||
*/
|
||||
public static final String SWITCH_TO_SAVE_KEY = "SWITCH_TO_SAVE_KEY_";
|
||||
|
||||
|
||||
// =================== token-style 相关 ===================
|
||||
|
||||
/**
|
||||
* token风格: uuid
|
||||
*/
|
||||
public static final String TOKEN_STYLE_UUID = "uuid";
|
||||
|
||||
/**
|
||||
* token风格: 简单uuid (不带下划线)
|
||||
*/
|
||||
public static final String TOKEN_STYLE_SIMPLE_UUID = "simple-uuid";
|
||||
|
||||
/**
|
||||
* token风格: 32位随机字符串
|
||||
*/
|
||||
public static final String TOKEN_STYLE_RANDOM_32 = "random-32";
|
||||
|
||||
/**
|
||||
* token风格: 64位随机字符串
|
||||
*/
|
||||
public static final String TOKEN_STYLE_RANDOM_64 = "random-64";
|
||||
|
||||
/**
|
||||
* token风格: 128位随机字符串
|
||||
*/
|
||||
public static final String TOKEN_STYLE_RANDOM_128 = "random-128";
|
||||
|
||||
/**
|
||||
* token风格: tik风格 (2_14_16)
|
||||
*/
|
||||
public static final String TOKEN_STYLE_RANDOM_TIK = "tik";
|
||||
|
||||
|
||||
}
|
||||
|
@ -7,31 +7,28 @@ import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* sa-token 内部代码工具类
|
||||
* sa-token 内部代码工具类
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaTokenInsideUtil {
|
||||
|
||||
|
||||
/**
|
||||
* 打印 sa-token 版本字符画
|
||||
* 打印 sa-token 版本字符画
|
||||
*/
|
||||
public static void printSaToken() {
|
||||
String str =
|
||||
"____ ____ ___ ____ _ _ ____ _ _ \r\n" +
|
||||
"[__ |__| __ | | | |_/ |___ |\\ | \r\n" +
|
||||
"___] | | | |__| | \\_ |___ | \\| \r\n" +
|
||||
"sa-token:" + SaTokenConsts.VERSION_NO + " \r\n" +
|
||||
"GitHub:" + SaTokenConsts.GITHUB_URL; // + "\r\n";
|
||||
String str = "____ ____ ___ ____ _ _ ____ _ _ \r\n" + "[__ |__| __ | | | |_/ |___ |\\ | \r\n"
|
||||
+ "___] | | | |__| | \\_ |___ | \\| \r\n" + "sa-token:" + SaTokenConsts.VERSION_NO
|
||||
+ " \r\n" + "GitHub:" + SaTokenConsts.GITHUB_URL; // + "\r\n";
|
||||
System.out.println(str);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 生成指定长度的随机字符串
|
||||
* @param length 字符串的长度
|
||||
* @return 一个随机字符串
|
||||
* 生成指定长度的随机字符串
|
||||
*
|
||||
* @param length 字符串的长度
|
||||
* @return 一个随机字符串
|
||||
*/
|
||||
public static String getRandomString(int length) {
|
||||
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
@ -43,68 +40,69 @@ public class SaTokenInsideUtil {
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 以当前时间戳和随机int数字拼接一个随机字符串
|
||||
* @return 随机字符串
|
||||
* 以当前时间戳和随机int数字拼接一个随机字符串
|
||||
*
|
||||
* @return 随机字符串
|
||||
*/
|
||||
public static String getMarking28() {
|
||||
return System.currentTimeMillis() + "" + new Random().nextInt(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 从集合里查询数据
|
||||
* @param dataList 数据集合
|
||||
* @param prefix 前缀
|
||||
* @param keyword 关键字
|
||||
* @param start 起始位置 (-1代表查询所有)
|
||||
* @param size 获取条数
|
||||
* @return 符合条件的新数据集合
|
||||
*
|
||||
* @param dataList 数据集合
|
||||
* @param prefix 前缀
|
||||
* @param keyword 关键字
|
||||
* @param start 起始位置 (-1代表查询所有)
|
||||
* @param size 获取条数
|
||||
* @return 符合条件的新数据集合
|
||||
*/
|
||||
public static List<String> searchList(Collection<String> dataList, String prefix, String keyword, int start, int size) {
|
||||
if(prefix == null) {
|
||||
public static List<String> searchList(Collection<String> dataList, String prefix, String keyword, int start,
|
||||
int size) {
|
||||
if (prefix == null) {
|
||||
prefix = "";
|
||||
}
|
||||
if(keyword == null) {
|
||||
if (keyword == null) {
|
||||
keyword = "";
|
||||
}
|
||||
// 挑选出所有符合条件的
|
||||
// 挑选出所有符合条件的
|
||||
List<String> list = new ArrayList<String>();
|
||||
Iterator<String> keys = dataList.iterator();
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
if(key.startsWith(prefix) && key.indexOf(keyword) > -1) {
|
||||
if (key.startsWith(prefix) && key.indexOf(keyword) > -1) {
|
||||
list.add(key);
|
||||
}
|
||||
}
|
||||
// 取指定段数据
|
||||
return searchList(list, start, size);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 从集合里查询数据
|
||||
* @param list 数据集合
|
||||
*
|
||||
* @param list 数据集合
|
||||
* @param start 起始位置 (-1代表查询所有)
|
||||
* @param size 获取条数
|
||||
* @return 符合条件的新数据集合
|
||||
* @param size 获取条数
|
||||
* @return 符合条件的新数据集合
|
||||
*/
|
||||
public static List<String> searchList(List<String> list, int start, int size) {
|
||||
// 取指定段数据
|
||||
if(start < 0) {
|
||||
if (start < 0) {
|
||||
return list;
|
||||
}
|
||||
int end = start + size;
|
||||
List<String> list2 = new ArrayList<String>();
|
||||
for (int i = start; i < end; i++) {
|
||||
if(i >= list.size()) {
|
||||
if (i >= list.size()) {
|
||||
return list2;
|
||||
}
|
||||
list2.add(list.get(i));
|
||||
}
|
||||
return list2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -21,7 +21,10 @@ import cn.dev33.satoken.session.SaSession;
|
||||
import cn.dev33.satoken.util.SaTokenInsideUtil;
|
||||
|
||||
/**
|
||||
* sa-token持久层的实现类, 基于redis (to jackson)
|
||||
* sa-token持久层的实现类, 基于redis (使用 jackson 序列化方式)
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class SaTokenDaoRedisJackson implements SaTokenDao {
|
||||
@ -97,7 +100,8 @@ public class SaTokenDaoRedisJackson implements SaTokenDao {
|
||||
@Override
|
||||
public void updateValue(String key, String value) {
|
||||
long expire = getTimeout(key);
|
||||
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) { // -2 = 无此键
|
||||
// -2 = 无此键
|
||||
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {
|
||||
return;
|
||||
}
|
||||
this.setValue(key, value, expire);
|
||||
@ -167,7 +171,8 @@ public class SaTokenDaoRedisJackson implements SaTokenDao {
|
||||
@Override
|
||||
public void updateSession(SaSession session) {
|
||||
long expire = getSessionTimeout(session.getId());
|
||||
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) { // -2 = 无此键
|
||||
// -2 = 无此键
|
||||
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {
|
||||
return;
|
||||
}
|
||||
this.saveSession(session, expire);
|
||||
|
@ -18,12 +18,15 @@ import cn.dev33.satoken.util.SaTokenInsideUtil;
|
||||
|
||||
/**
|
||||
* sa-token持久层的实现类, 基于redis
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class SaTokenDaoRedis implements SaTokenDao {
|
||||
|
||||
/**
|
||||
* string专用
|
||||
* string专用
|
||||
*/
|
||||
@Autowired
|
||||
public StringRedisTemplate stringRedisTemplate;
|
||||
@ -52,7 +55,7 @@ public class SaTokenDaoRedis implements SaTokenDao {
|
||||
|
||||
|
||||
/**
|
||||
* 根据key获取value,如果没有,则返回空
|
||||
* 根据key获取value,如果没有,则返回空
|
||||
*/
|
||||
@Override
|
||||
public String getValue(String key) {
|
||||
@ -78,7 +81,8 @@ public class SaTokenDaoRedis implements SaTokenDao {
|
||||
@Override
|
||||
public void updateValue(String key, String value) {
|
||||
long expire = getTimeout(key);
|
||||
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) { // -2 = 无此键
|
||||
// -2 = 无此键
|
||||
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {
|
||||
return;
|
||||
}
|
||||
this.setValue(key, value, expire);
|
||||
@ -148,7 +152,8 @@ public class SaTokenDaoRedis implements SaTokenDao {
|
||||
@Override
|
||||
public void updateSession(SaSession session) {
|
||||
long expire = getSessionTimeout(session.getId());
|
||||
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) { // -2 = 无此键
|
||||
// -2 = 无此键
|
||||
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {
|
||||
return;
|
||||
}
|
||||
this.saveSession(session, expire);
|
||||
|
@ -11,7 +11,8 @@ import cn.dev33.satoken.stp.StpLogic;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
|
||||
/**
|
||||
* sa-token 基于 Spring Aop 的注解鉴权
|
||||
* sa-token 基于 Spring Aop 的注解鉴权
|
||||
*
|
||||
* @author kong
|
||||
*/
|
||||
@Aspect
|
||||
@ -19,46 +20,46 @@ import cn.dev33.satoken.stp.StpUtil;
|
||||
public class SaCheckAspect {
|
||||
|
||||
/**
|
||||
* 创建
|
||||
* 构建
|
||||
*/
|
||||
public SaCheckAspect() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取本切面使用的StpLogic
|
||||
* 获取本切面使用的StpLogic
|
||||
*/
|
||||
public StpLogic getStpLogic() {
|
||||
return StpUtil.stpLogic;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 定义AOP签名 (切入所有使用sa-token鉴权注解的方法)
|
||||
* 定义AOP签名 (切入所有使用sa-token鉴权注解的方法)
|
||||
*/
|
||||
public static final String POINTCUT_SIGN = "@within(cn.dev33.satoken.annotation.SaCheckLogin) || @annotation(cn.dev33.satoken.annotation.SaCheckLogin) || "
|
||||
+ "@within(cn.dev33.satoken.annotation.SaCheckRole) || @annotation(cn.dev33.satoken.annotation.SaCheckRole) || "
|
||||
+ "@within(cn.dev33.satoken.annotation.SaCheckPermission) || @annotation(cn.dev33.satoken.annotation.SaCheckPermission)";
|
||||
|
||||
/**
|
||||
* 声明AOP签名
|
||||
* 声明AOP签名
|
||||
*/
|
||||
@Pointcut(POINTCUT_SIGN)
|
||||
public void pointcut() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 环绕切入
|
||||
* 环绕切入
|
||||
*
|
||||
* @param joinPoint 切面对象
|
||||
* @return 底层方法执行后的返回值
|
||||
* @throws Throwable 底层方法抛出的异常
|
||||
* @throws Throwable 底层方法抛出的异常
|
||||
*/
|
||||
@Around("pointcut()")
|
||||
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
// 注解鉴权
|
||||
// 注解鉴权
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
getStpLogic().checkMethodAnnotation(signature.getMethod());
|
||||
try {
|
||||
// 执行原有逻辑
|
||||
// 执行原有逻辑
|
||||
Object obj = joinPoint.proceed();
|
||||
return obj;
|
||||
} catch (Throwable e) {
|
||||
|
@ -16,102 +16,108 @@ import cn.dev33.satoken.spring.SaTokenServletSpringImpl;
|
||||
import cn.dev33.satoken.stp.StpInterface;
|
||||
|
||||
/**
|
||||
* 利用spring的自动装配来加载开发者重写的Bean
|
||||
* 利用spring的自动装配来加载开发者重写的Bean
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class SaTokenSpringAutowired {
|
||||
|
||||
|
||||
/**
|
||||
* 获取配置Bean
|
||||
* @return 配置对象
|
||||
* 获取配置Bean
|
||||
*
|
||||
* @return 配置对象
|
||||
*/
|
||||
@Bean
|
||||
@ConfigurationProperties(prefix="spring.sa-token")
|
||||
@ConfigurationProperties(prefix = "spring.sa-token")
|
||||
public SaTokenConfig getSaTokenConfig() {
|
||||
return new SaTokenConfig();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 注入配置Bean
|
||||
* 注入配置Bean
|
||||
*
|
||||
* @param saTokenConfig 配置对象
|
||||
*/
|
||||
@Autowired
|
||||
public void setConfig(SaTokenConfig saTokenConfig){
|
||||
public void setConfig(SaTokenConfig saTokenConfig) {
|
||||
SaTokenManager.setConfig(saTokenConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注入持久化Bean
|
||||
* @param saTokenDao .
|
||||
* 注入持久化Bean
|
||||
*
|
||||
* @param saTokenDao SaTokenDao对象
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
public void setSaTokenDao(SaTokenDao saTokenDao){
|
||||
public void setSaTokenDao(SaTokenDao saTokenDao) {
|
||||
SaTokenManager.setSaTokenDao(saTokenDao);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注入权限认证Bean
|
||||
* @param stpInterface .
|
||||
* 注入权限认证Bean
|
||||
*
|
||||
* @param stpInterface StpInterface对象
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
public void setStpInterface(StpInterface stpInterface){
|
||||
public void setStpInterface(StpInterface stpInterface) {
|
||||
SaTokenManager.setStpInterface(stpInterface);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注入Cookie操作Bean
|
||||
* @param saTokenCookie .
|
||||
* 注入Cookie操作Bean
|
||||
*
|
||||
* @param saTokenCookie SaTokenCookie对象
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
public void setSaTokenCookie(SaTokenCookie saTokenCookie){
|
||||
public void setSaTokenCookie(SaTokenCookie saTokenCookie) {
|
||||
SaTokenManager.setSaTokenCookie(saTokenCookie);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注入框架行为Bean
|
||||
* @param saTokenAction .
|
||||
* 注入框架行为Bean
|
||||
*
|
||||
* @param saTokenAction SaTokenAction对象
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
public void setSaTokenAction(SaTokenAction saTokenAction){
|
||||
public void setSaTokenAction(SaTokenAction saTokenAction) {
|
||||
SaTokenManager.setSaTokenAction(saTokenAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Servlet操作Bean (Spring版)
|
||||
* @return Servlet操作Bean (Spring版)
|
||||
* 获取Servlet操作Bean (Spring版)
|
||||
*
|
||||
* @return Servlet操作Bean (Spring版)
|
||||
*/
|
||||
@Bean
|
||||
public SaTokenServlet getSaTokenServlet() {
|
||||
return new SaTokenServletSpringImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* 注入Servlet操作Bean
|
||||
* @param saTokenServlet .
|
||||
*/
|
||||
@Autowired
|
||||
public void setSaTokenServlet(SaTokenServlet saTokenServlet){
|
||||
SaTokenManager.setSaTokenServlet(saTokenServlet);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 路由匹配器
|
||||
* 注入Servlet操作Bean
|
||||
*
|
||||
* @param saTokenServlet SaTokenServlet对象
|
||||
*/
|
||||
@Autowired
|
||||
public void setSaTokenServlet(SaTokenServlet saTokenServlet) {
|
||||
SaTokenManager.setSaTokenServlet(saTokenServlet);
|
||||
}
|
||||
|
||||
/**
|
||||
* 路由匹配器
|
||||
*/
|
||||
public static PathMatcher pathMatcher;
|
||||
|
||||
/**
|
||||
* 利用自动匹配特性,获取SpringMVC框架内部使用的路由匹配器
|
||||
* 利用自动匹配特性,获取SpringMVC框架内部使用的路由匹配器
|
||||
*
|
||||
* @param pathMatcher 要设置的 pathMatcher
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
public static void setPathMatcher(PathMatcher pathMatcher) {
|
||||
SaTokenSpringAutowired.pathMatcher = pathMatcher;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -12,29 +12,29 @@ import cn.dev33.satoken.stp.StpLogic;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
|
||||
/**
|
||||
* 注解式鉴权 - 拦截器
|
||||
* 注解式鉴权 - 拦截器
|
||||
*
|
||||
* @author kong
|
||||
*/
|
||||
public class SaAnnotationInterceptor implements HandlerInterceptor {
|
||||
|
||||
|
||||
/**
|
||||
* 底层的 StpLogic 对象
|
||||
* 在进行注解鉴权时使用的 StpLogic 对象
|
||||
*/
|
||||
public StpLogic stpLogic = null;
|
||||
|
||||
|
||||
/**
|
||||
* @return 底层的 StpLogic 对象
|
||||
* @return 在进行注解鉴权时使用的 StpLogic 对象
|
||||
*/
|
||||
public StpLogic getStpLogic() {
|
||||
if(stpLogic == null) {
|
||||
if (stpLogic == null) {
|
||||
stpLogic = StpUtil.stpLogic;
|
||||
}
|
||||
return stpLogic;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stpLogic 底层的 StpLogic 对象
|
||||
* @param stpLogic 在进行注解鉴权时使用的 StpLogic 对象
|
||||
* @return 拦截器自身
|
||||
*/
|
||||
public SaAnnotationInterceptor setStpLogic(StpLogic stpLogic) {
|
||||
@ -42,33 +42,30 @@ public class SaAnnotationInterceptor implements HandlerInterceptor {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建,并指定一个默认的 StpLogic
|
||||
* 构建: 注解式鉴权 - 拦截器
|
||||
*/
|
||||
public SaAnnotationInterceptor() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 每次请求之前触发的方法
|
||||
* 每次请求之前触发的方法
|
||||
*/
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
|
||||
throws Exception {
|
||||
|
||||
|
||||
// 获取处理method
|
||||
if (handler instanceof HandlerMethod == false) {
|
||||
return true;
|
||||
}
|
||||
Method method = ((HandlerMethod) handler).getMethod();
|
||||
|
||||
// 进行验证
|
||||
|
||||
// 进行验证
|
||||
getStpLogic().checkMethodAnnotation(method);
|
||||
|
||||
// 通过验证
|
||||
|
||||
// 通过验证
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -5,16 +5,18 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* 执行验证方法的辅助类
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public interface SaRouteFunction {
|
||||
|
||||
/**
|
||||
* 执行验证的方法
|
||||
* @param request request对象
|
||||
* @param response response对象
|
||||
* @param handler 处理对象
|
||||
* 执行验证的方法
|
||||
*
|
||||
* @param request request对象
|
||||
* @param response response对象
|
||||
* @param handler 处理对象
|
||||
*/
|
||||
public void run(HttpServletRequest request, HttpServletResponse response, Object handler);
|
||||
|
||||
|
@ -19,7 +19,7 @@ import cn.dev33.satoken.fun.SaFunction;
|
||||
public class SaRouterUtil {
|
||||
|
||||
/**
|
||||
* 在进行路由匹配时所使用的的 PathMatcher 对象
|
||||
* 在进行路由匹配时所使用的 PathMatcher 对象
|
||||
*/
|
||||
private static PathMatcher pathMatcher;
|
||||
|
||||
|
@ -6,14 +6,15 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import cn.dev33.satoken.servlet.SaTokenServlet;
|
||||
|
||||
/**
|
||||
* sa-token 对cookie的相关操作 接口实现类
|
||||
* sa-token 对cookie的相关操作 接口实现类
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaTokenServletSpringImpl implements SaTokenServlet {
|
||||
|
||||
/**
|
||||
* 获取当前请求的Request对象
|
||||
* 获取当前请求的Request对象
|
||||
*/
|
||||
@Override
|
||||
public HttpServletRequest getRequest() {
|
||||
@ -21,11 +22,11 @@ public class SaTokenServletSpringImpl implements SaTokenServlet {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前请求的Response对象
|
||||
* 获取当前请求的Response对象
|
||||
*/
|
||||
@Override
|
||||
public HttpServletResponse getResponse() {
|
||||
return SpringMVCUtil.getResponse();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
|
||||
/**
|
||||
* SpringMVC相关操作
|
||||
* @author kong
|
||||
@ -18,9 +20,9 @@ public class SpringMVCUtil {
|
||||
* @return request
|
||||
*/
|
||||
public static HttpServletRequest getRequest() {
|
||||
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();// 大善人SpringMVC提供的封装
|
||||
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
if(servletRequestAttributes == null) {
|
||||
throw new RuntimeException("当前环境非JavaWeb");
|
||||
throw new SaTokenException("非Web上下文无法获取Request");
|
||||
}
|
||||
return servletRequestAttributes.getRequest();
|
||||
}
|
||||
@ -30,9 +32,9 @@ public class SpringMVCUtil {
|
||||
* @return response
|
||||
*/
|
||||
public static HttpServletResponse getResponse() {
|
||||
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();// 大善人SpringMVC提供的封装
|
||||
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
if(servletRequestAttributes == null) {
|
||||
throw new RuntimeException("当前环境非JavaWeb");
|
||||
throw new SaTokenException("非Web上下文无法获取Request");
|
||||
}
|
||||
return servletRequestAttributes.getResponse();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user