mirror of
https://gitee.com/dromara/sa-token.git
synced 2026-02-27 16:50:24 +08:00
Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50ffda7bef | ||
|
|
a122a8b083 | ||
|
|
69ce298a8a | ||
|
|
f92e64b9cf | ||
|
|
d3138cefc8 | ||
|
|
71f2522f08 | ||
|
|
a5e9bd6714 | ||
|
|
27bb436a90 | ||
|
|
d75c91f0ab | ||
|
|
8ee9f215a6 |
@@ -1,5 +1,8 @@
|
|||||||
package cn.dev33.satoken;
|
package cn.dev33.satoken;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import cn.dev33.satoken.action.SaTokenAction;
|
import cn.dev33.satoken.action.SaTokenAction;
|
||||||
import cn.dev33.satoken.action.SaTokenActionDefaultImpl;
|
import cn.dev33.satoken.action.SaTokenActionDefaultImpl;
|
||||||
import cn.dev33.satoken.config.SaTokenConfig;
|
import cn.dev33.satoken.config.SaTokenConfig;
|
||||||
@@ -12,6 +15,7 @@ import cn.dev33.satoken.servlet.SaTokenServlet;
|
|||||||
import cn.dev33.satoken.servlet.SaTokenServletDefaultImpl;
|
import cn.dev33.satoken.servlet.SaTokenServletDefaultImpl;
|
||||||
import cn.dev33.satoken.stp.StpInterface;
|
import cn.dev33.satoken.stp.StpInterface;
|
||||||
import cn.dev33.satoken.stp.StpInterfaceDefaultImpl;
|
import cn.dev33.satoken.stp.StpInterfaceDefaultImpl;
|
||||||
|
import cn.dev33.satoken.stp.StpLogic;
|
||||||
import cn.dev33.satoken.util.SaTokenInsideUtil;
|
import cn.dev33.satoken.util.SaTokenInsideUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,129 +25,148 @@ import cn.dev33.satoken.util.SaTokenInsideUtil;
|
|||||||
*/
|
*/
|
||||||
public class SaTokenManager {
|
public class SaTokenManager {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 配置文件 Bean
|
* 配置文件 Bean
|
||||||
*/
|
*/
|
||||||
private static SaTokenConfig config;
|
private static SaTokenConfig config;
|
||||||
public static SaTokenConfig getConfig() {
|
|
||||||
if (config == null) {
|
|
||||||
initConfig();
|
|
||||||
}
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
public static void setConfig(SaTokenConfig config) {
|
public static void setConfig(SaTokenConfig config) {
|
||||||
SaTokenManager.config = config;
|
SaTokenManager.config = config;
|
||||||
if(config.getIsV()) {
|
if(config.getIsV()) {
|
||||||
SaTokenInsideUtil.printSaToken();
|
SaTokenInsideUtil.printSaToken();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public synchronized static void initConfig() {
|
public static SaTokenConfig getConfig() {
|
||||||
if (config == null) {
|
if (config == null) {
|
||||||
setConfig(SaTokenConfigFactory.createConfig());
|
// 如果对象为空,则使用框架默认方式初始化
|
||||||
|
synchronized (SaTokenManager.class) {
|
||||||
|
if (config == null) {
|
||||||
|
setConfig(SaTokenConfigFactory.createConfig());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 持久化 Bean
|
* 持久化 Bean
|
||||||
*/
|
*/
|
||||||
public static SaTokenDao saTokenDao;
|
private static SaTokenDao saTokenDao;
|
||||||
public static SaTokenDao getSaTokenDao() {
|
|
||||||
if (saTokenDao == null) {
|
|
||||||
initSaTokenDao();
|
|
||||||
}
|
|
||||||
return saTokenDao;
|
|
||||||
}
|
|
||||||
public static void setSaTokenDao(SaTokenDao saTokenDao) {
|
public static void setSaTokenDao(SaTokenDao saTokenDao) {
|
||||||
if(SaTokenManager.saTokenDao != null && (SaTokenManager.saTokenDao instanceof SaTokenDaoDefaultImpl)) {
|
if(SaTokenManager.saTokenDao != null && (SaTokenManager.saTokenDao instanceof SaTokenDaoDefaultImpl)) {
|
||||||
((SaTokenDaoDefaultImpl)SaTokenManager.saTokenDao).endRefreshTimer();
|
((SaTokenDaoDefaultImpl)SaTokenManager.saTokenDao).endRefreshTimer();
|
||||||
}
|
}
|
||||||
SaTokenManager.saTokenDao = saTokenDao;
|
SaTokenManager.saTokenDao = saTokenDao;
|
||||||
}
|
}
|
||||||
public synchronized static void initSaTokenDao() {
|
public static SaTokenDao getSaTokenDao() {
|
||||||
if (saTokenDao == null) {
|
if (saTokenDao == null) {
|
||||||
setSaTokenDao(new SaTokenDaoDefaultImpl());
|
// 如果对象为空,则使用框架默认方式初始化
|
||||||
|
synchronized (SaTokenManager.class) {
|
||||||
|
if (saTokenDao == null) {
|
||||||
|
setSaTokenDao(new SaTokenDaoDefaultImpl());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return saTokenDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 权限认证 Bean
|
* 权限认证 Bean
|
||||||
*/
|
*/
|
||||||
public static StpInterface stpInterface;
|
private static StpInterface stpInterface;
|
||||||
public static StpInterface getStpInterface() {
|
|
||||||
if (stpInterface == null) {
|
|
||||||
initStpInterface();
|
|
||||||
}
|
|
||||||
return stpInterface;
|
|
||||||
}
|
|
||||||
public static void setStpInterface(StpInterface stpInterface) {
|
public static void setStpInterface(StpInterface stpInterface) {
|
||||||
SaTokenManager.stpInterface = stpInterface;
|
SaTokenManager.stpInterface = stpInterface;
|
||||||
}
|
}
|
||||||
public synchronized static void initStpInterface() {
|
public static StpInterface getStpInterface() {
|
||||||
if (stpInterface == null) {
|
if (stpInterface == null) {
|
||||||
setStpInterface(new StpInterfaceDefaultImpl());
|
// 如果对象为空,则使用框架默认方式初始化
|
||||||
|
synchronized (SaTokenManager.class) {
|
||||||
|
if (stpInterface == null) {
|
||||||
|
setStpInterface(new StpInterfaceDefaultImpl());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return stpInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 框架行为 Bean
|
* 框架行为 Bean
|
||||||
*/
|
*/
|
||||||
public static SaTokenAction saTokenAction;
|
private static SaTokenAction saTokenAction;
|
||||||
public static SaTokenAction getSaTokenAction() {
|
|
||||||
if (saTokenAction == null) {
|
|
||||||
initSaTokenAction();
|
|
||||||
}
|
|
||||||
return saTokenAction;
|
|
||||||
}
|
|
||||||
public static void setSaTokenAction(SaTokenAction saTokenAction) {
|
public static void setSaTokenAction(SaTokenAction saTokenAction) {
|
||||||
SaTokenManager.saTokenAction = saTokenAction;
|
SaTokenManager.saTokenAction = saTokenAction;
|
||||||
}
|
}
|
||||||
public synchronized static void initSaTokenAction() {
|
public static SaTokenAction getSaTokenAction() {
|
||||||
if (saTokenAction == null) {
|
if (saTokenAction == null) {
|
||||||
setSaTokenAction(new SaTokenActionDefaultImpl());
|
// 如果对象为空,则使用框架默认方式初始化
|
||||||
|
synchronized (SaTokenManager.class) {
|
||||||
|
if (saTokenAction == null) {
|
||||||
|
setSaTokenAction(new SaTokenActionDefaultImpl());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return saTokenAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cookie操作 Bean
|
* Cookie操作 Bean
|
||||||
*/
|
*/
|
||||||
public static SaTokenCookie saTokenCookie;
|
private static SaTokenCookie saTokenCookie;
|
||||||
public static SaTokenCookie getSaTokenCookie() {
|
|
||||||
if (saTokenCookie == null) {
|
|
||||||
initSaTokenCookie();
|
|
||||||
}
|
|
||||||
return saTokenCookie;
|
|
||||||
}
|
|
||||||
public static void setSaTokenCookie(SaTokenCookie saTokenCookie) {
|
public static void setSaTokenCookie(SaTokenCookie saTokenCookie) {
|
||||||
SaTokenManager.saTokenCookie = saTokenCookie;
|
SaTokenManager.saTokenCookie = saTokenCookie;
|
||||||
}
|
}
|
||||||
public synchronized static void initSaTokenCookie() {
|
public static SaTokenCookie getSaTokenCookie() {
|
||||||
if (saTokenCookie == null) {
|
if (saTokenCookie == null) {
|
||||||
setSaTokenCookie(new SaTokenCookieDefaultImpl());
|
// 如果对象为空,则使用框架默认方式初始化
|
||||||
|
synchronized (SaTokenManager.class) {
|
||||||
|
if (saTokenCookie == null) {
|
||||||
|
setSaTokenCookie(new SaTokenCookieDefaultImpl());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return saTokenCookie;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Servlet操作 Bean
|
* Servlet操作 Bean
|
||||||
*/
|
*/
|
||||||
public static SaTokenServlet saTokenServlet;
|
private static SaTokenServlet saTokenServlet;
|
||||||
public static SaTokenServlet getSaTokenServlet() {
|
|
||||||
if (saTokenServlet == null) {
|
|
||||||
initSaTokenServlet();
|
|
||||||
}
|
|
||||||
return saTokenServlet;
|
|
||||||
}
|
|
||||||
public static void setSaTokenServlet(SaTokenServlet saTokenServlet) {
|
public static void setSaTokenServlet(SaTokenServlet saTokenServlet) {
|
||||||
SaTokenManager.saTokenServlet = saTokenServlet;
|
SaTokenManager.saTokenServlet = saTokenServlet;
|
||||||
}
|
}
|
||||||
public synchronized static void initSaTokenServlet() {
|
public static SaTokenServlet getSaTokenServlet() {
|
||||||
if (saTokenServlet == null) {
|
if (saTokenServlet == null) {
|
||||||
setSaTokenServlet(new SaTokenServletDefaultImpl());
|
// 如果对象为空,则使用框架默认方式初始化
|
||||||
|
if (saTokenServlet == null) {
|
||||||
|
setSaTokenServlet(new SaTokenServletDefaultImpl());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return saTokenServlet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StpLogic集合, 记录框架所有成功初始化的StpLogic
|
||||||
|
*/
|
||||||
|
public static Map<String, StpLogic> stpLogicMap = new HashMap<String, StpLogic>();
|
||||||
|
/**
|
||||||
|
* 向集合中 put 一个 StpLogic
|
||||||
|
* @param stpLogic
|
||||||
|
*/
|
||||||
|
public static void putStpLogic(StpLogic stpLogic) {
|
||||||
|
stpLogicMap.put(stpLogic.getLoginKey(), stpLogic);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 根据 LoginKey 获取对应的StpLogic,如果不存在则返回null
|
||||||
|
* @param loginKey 对应的LoginKey
|
||||||
|
* @return 对应的StpLogic
|
||||||
|
*/
|
||||||
|
public static StpLogic getStpLogic(String loginKey) {
|
||||||
|
for (String key : stpLogicMap.keySet()) {
|
||||||
|
if(key.equals(loginKey)) {
|
||||||
|
return stpLogicMap.get(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ public class SaTokenConfig {
|
|||||||
|
|
||||||
/** 写入Cookie时显式指定的作用域, 常用于单点登录二级域名共享Cookie的场景 */
|
/** 写入Cookie时显式指定的作用域, 常用于单点登录二级域名共享Cookie的场景 */
|
||||||
private String cookieDomain;
|
private String cookieDomain;
|
||||||
|
|
||||||
|
/** token前缀, 格式样例(satoken: Bearer xxxx-xxxx-xxxx-xxxx) */
|
||||||
|
private String tokenPrefix;
|
||||||
|
|
||||||
/** 是否在初始化配置时打印版本字符画 */
|
/** 是否在初始化配置时打印版本字符画 */
|
||||||
private Boolean isV = true;
|
private Boolean isV = true;
|
||||||
@@ -269,6 +272,22 @@ public class SaTokenConfig {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return token前缀, 格式样例(satoken: Bearer xxxx-xxxx-xxxx-xxxx)
|
||||||
|
*/
|
||||||
|
public String getTokenPrefix() {
|
||||||
|
return tokenPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param tokenPrefix token前缀, 格式样例(satoken: Bearer xxxx-xxxx-xxxx-xxxx)
|
||||||
|
* @return 对象自身
|
||||||
|
*/
|
||||||
|
public SaTokenConfig setTokenPrefix(String tokenPrefix) {
|
||||||
|
this.tokenPrefix = tokenPrefix;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return 是否在初始化配置时打印版本字符画
|
* @return 是否在初始化配置时打印版本字符画
|
||||||
*/
|
*/
|
||||||
@@ -285,6 +304,7 @@ public class SaTokenConfig {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* toString
|
* toString
|
||||||
@@ -295,8 +315,8 @@ public class SaTokenConfig {
|
|||||||
+ ", allowConcurrentLogin=" + allowConcurrentLogin + ", isShare=" + isShare + ", isReadBody="
|
+ ", allowConcurrentLogin=" + allowConcurrentLogin + ", isShare=" + isShare + ", isReadBody="
|
||||||
+ isReadBody + ", isReadHead=" + isReadHead + ", isReadCookie=" + isReadCookie + ", tokenStyle="
|
+ isReadBody + ", isReadHead=" + isReadHead + ", isReadCookie=" + isReadCookie + ", tokenStyle="
|
||||||
+ tokenStyle + ", dataRefreshPeriod=" + dataRefreshPeriod + ", tokenSessionCheckLogin="
|
+ tokenStyle + ", dataRefreshPeriod=" + dataRefreshPeriod + ", tokenSessionCheckLogin="
|
||||||
+ tokenSessionCheckLogin + ", autoRenew=" + autoRenew + ", cookieDomain=" + cookieDomain + ", isV="
|
+ tokenSessionCheckLogin + ", autoRenew=" + autoRenew + ", cookieDomain=" + cookieDomain
|
||||||
+ isV + "]";
|
+ ", tokenPrefix=" + tokenPrefix + ", isV=" + isV + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -237,8 +237,39 @@ public class SaSession implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------- 一些操作
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将这个Session从持久库更新一下
|
||||||
|
*/
|
||||||
|
public void update() {
|
||||||
|
SaTokenManager.getSaTokenDao().updateSession(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 注销会话 (注销后,此session会话将不再存储服务器上) */
|
||||||
|
public void logout() {
|
||||||
|
SaTokenManager.getSaTokenDao().deleteSession(this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 当Session上的tokenSign数量为零时,注销会话 */
|
||||||
|
public void logoutByTokenSignCountToZero() {
|
||||||
|
if (tokenSignList.size() == 0) {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------- 存取值 (类型转换)
|
// ----------------------- 存取值 (类型转换)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断一个值是否为null
|
||||||
|
* @param value 指定值
|
||||||
|
* @return 此value是否为null
|
||||||
|
*/
|
||||||
|
public boolean valueIsNull(Object value) {
|
||||||
|
return value == null || value.equals("");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从Session中取值,并转化为Object类型
|
* 从Session中取值,并转化为Object类型
|
||||||
* @param key key
|
* @param key key
|
||||||
@@ -273,36 +304,19 @@ public class SaSession implements Serializable {
|
|||||||
}
|
}
|
||||||
return Integer.valueOf(String.valueOf(value));
|
return Integer.valueOf(String.valueOf(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断一个值是否为null
|
|
||||||
* @param value 指定值
|
|
||||||
* @return 此value是否为null
|
|
||||||
*/
|
|
||||||
public boolean valueIsNull(Object value) {
|
|
||||||
return value == null || value.equals("");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------- 一些操作
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将这个Session从持久库更新一下
|
* 从Session中取值,并转化为long类型,如果value为空,则返回0
|
||||||
|
* @param key key
|
||||||
|
* @return 值
|
||||||
*/
|
*/
|
||||||
public void update() {
|
public long getLong(String key) {
|
||||||
SaTokenManager.getSaTokenDao().updateSession(this);
|
Object value = getObject(key);
|
||||||
}
|
if(valueIsNull(value)) {
|
||||||
|
return 0;
|
||||||
/** 注销会话 (注销后,此session会话将不再存储服务器上) */
|
|
||||||
public void logout() {
|
|
||||||
SaTokenManager.getSaTokenDao().deleteSession(this.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 当Session上的tokenSign数量为零时,注销会话 */
|
|
||||||
public void logoutByTokenSignCountToZero() {
|
|
||||||
if (tokenSignList.size() == 0) {
|
|
||||||
logout();
|
|
||||||
}
|
}
|
||||||
|
return Long.valueOf(String.valueOf(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import cn.dev33.satoken.fun.SaFunction;
|
|||||||
import cn.dev33.satoken.session.SaSession;
|
import cn.dev33.satoken.session.SaSession;
|
||||||
import cn.dev33.satoken.session.TokenSign;
|
import cn.dev33.satoken.session.TokenSign;
|
||||||
import cn.dev33.satoken.util.SaTokenConsts;
|
import cn.dev33.satoken.util.SaTokenConsts;
|
||||||
|
import cn.dev33.satoken.util.SaTokenInsideUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sa-token 权限验证,逻辑实现类
|
* sa-token 权限验证,逻辑实现类
|
||||||
@@ -44,6 +45,8 @@ public class StpLogic {
|
|||||||
*/
|
*/
|
||||||
public StpLogic(String loginKey) {
|
public StpLogic(String loginKey) {
|
||||||
this.loginKey = loginKey;
|
this.loginKey = loginKey;
|
||||||
|
// 在 SaTokenManager 中记录下此 StpLogic,以便根据 LoginKey 进行查找此对象
|
||||||
|
SaTokenManager.putStpLogic(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,6 +87,23 @@ public class StpLogic {
|
|||||||
return SaTokenManager.getSaTokenAction().createToken(loginId, loginKey);
|
return SaTokenManager.getSaTokenAction().createToken(loginId, loginKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在当前会话写入当前tokenValue
|
||||||
|
* @param tokenValue token值
|
||||||
|
*/
|
||||||
|
public void setTokenValue(String tokenValue, int cookieTimeout){
|
||||||
|
// 将token保存到本次request里
|
||||||
|
HttpServletRequest request = SaTokenManager.getSaTokenServlet().getRequest();
|
||||||
|
request.setAttribute(splicingKeyJustCreatedSave(), tokenValue);
|
||||||
|
// 注入Cookie
|
||||||
|
SaTokenConfig config = getConfig();
|
||||||
|
if(config.getIsReadCookie() == true){
|
||||||
|
HttpServletResponse response = SaTokenManager.getSaTokenServlet().getResponse();
|
||||||
|
SaTokenManager.getSaTokenCookie().addCookie(response, getTokenName(), tokenValue,
|
||||||
|
"/", config.getCookieDomain(), cookieTimeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前tokenValue
|
* 获取当前tokenValue
|
||||||
* @return 当前tokenValue
|
* @return 当前tokenValue
|
||||||
@@ -115,7 +135,16 @@ public class StpLogic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. 返回
|
// 5. 如果打开了前缀模式
|
||||||
|
String tokenPrefix = getConfig().getTokenPrefix();
|
||||||
|
if(SaTokenInsideUtil.isEmpty(tokenPrefix) == false && SaTokenInsideUtil.isEmpty(tokenValue) == false) {
|
||||||
|
// 如果token以指定的前缀开头, 则裁剪掉它
|
||||||
|
if(tokenValue.startsWith(tokenPrefix + " ")) {
|
||||||
|
tokenValue = tokenValue.substring(tokenPrefix.length() + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 返回
|
||||||
return tokenValue;
|
return tokenValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,7 +204,6 @@ public class StpLogic {
|
|||||||
public void setLoginId(Object loginId, SaLoginModel loginModel) {
|
public void setLoginId(Object loginId, SaLoginModel loginModel) {
|
||||||
|
|
||||||
// ------ 1、获取相应对象
|
// ------ 1、获取相应对象
|
||||||
HttpServletRequest request = SaTokenManager.getSaTokenServlet().getRequest();
|
|
||||||
SaTokenConfig config = getConfig();
|
SaTokenConfig config = getConfig();
|
||||||
SaTokenDao dao = SaTokenManager.getSaTokenDao();
|
SaTokenDao dao = SaTokenManager.getSaTokenDao();
|
||||||
loginModel.build(config);
|
loginModel.build(config);
|
||||||
@@ -190,7 +218,7 @@ public class StpLogic {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// --- 如果不允许并发登录
|
// --- 如果不允许并发登录
|
||||||
// 如果此时[id-session]不为null,说明此账号在其他地正在登录,现在需要先把其它地的同设备token标记为被顶下线
|
// 如果此时[user-session]不为null,说明此账号在其他地正在登录,现在需要先把其它地的同设备token标记为被顶下线
|
||||||
SaSession session = getSessionByLoginId(loginId, false);
|
SaSession session = getSessionByLoginId(loginId, false);
|
||||||
if(session != null) {
|
if(session != null) {
|
||||||
List<TokenSign> tokenSignList = session.getTokenSignList();
|
List<TokenSign> tokenSignList = session.getTokenSignList();
|
||||||
@@ -200,7 +228,7 @@ public class StpLogic {
|
|||||||
dao.update(splicingKeyTokenValue(tokenSign.getValue()), NotLoginException.BE_REPLACED);
|
dao.update(splicingKeyTokenValue(tokenSign.getValue()), NotLoginException.BE_REPLACED);
|
||||||
// 2. 清理掉[token-最后操作时间]
|
// 2. 清理掉[token-最后操作时间]
|
||||||
clearLastActivity(tokenSign.getValue());
|
clearLastActivity(tokenSign.getValue());
|
||||||
// 3. 清理账号session上的token签名记录
|
// 3. 清理user-session上的token签名记录
|
||||||
session.removeTokenSign(tokenSign.getValue());
|
session.removeTokenSign(tokenSign.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -227,16 +255,10 @@ public class StpLogic {
|
|||||||
// ------ 4. 持久化其它数据
|
// ------ 4. 持久化其它数据
|
||||||
// token -> uid
|
// token -> uid
|
||||||
dao.set(splicingKeyTokenValue(tokenValue), String.valueOf(loginId), loginModel.getTimeout());
|
dao.set(splicingKeyTokenValue(tokenValue), String.valueOf(loginId), loginModel.getTimeout());
|
||||||
// 将token保存到本次request里
|
|
||||||
request.setAttribute(splicingKeyJustCreatedSave(), tokenValue);
|
|
||||||
// 写入 [最后操作时间]
|
// 写入 [最后操作时间]
|
||||||
setLastActivityToNow(tokenValue);
|
setLastActivityToNow(tokenValue);
|
||||||
// 注入Cookie
|
// 在当前会话写入当前tokenValue
|
||||||
if(config.getIsReadCookie() == true){
|
setTokenValue(tokenValue, loginModel.getCookieTimeout());
|
||||||
HttpServletResponse response = SaTokenManager.getSaTokenServlet().getResponse();
|
|
||||||
SaTokenManager.getSaTokenCookie().addCookie(response, getTokenName(), tokenValue,
|
|
||||||
"/", config.getCookieDomain(), loginModel.getCookieTimeout());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -577,16 +599,11 @@ public class StpLogic {
|
|||||||
if(tokenValue == null || Objects.equals(tokenValue, "")) {
|
if(tokenValue == null || Objects.equals(tokenValue, "")) {
|
||||||
// 随机一个token送给Ta
|
// 随机一个token送给Ta
|
||||||
tokenValue = createTokenValue(null);
|
tokenValue = createTokenValue(null);
|
||||||
// Request做上标记
|
|
||||||
SaTokenManager.getSaTokenServlet().getRequest().setAttribute(splicingKeyJustCreatedSave(), tokenValue);
|
|
||||||
// 写入 [最后操作时间]
|
// 写入 [最后操作时间]
|
||||||
setLastActivityToNow(tokenValue);
|
setLastActivityToNow(tokenValue);
|
||||||
// cookie注入
|
// 在当前会话写入这个tokenValue
|
||||||
if(getConfig().getIsReadCookie() == true){
|
int cookieTimeout = (int)(getConfig().getTimeout() == SaTokenDao.NEVER_EXPIRE ? Integer.MAX_VALUE : getConfig().getTimeout());
|
||||||
int cookieTimeout = (int)(getConfig().getTimeout() == SaTokenDao.NEVER_EXPIRE ? Integer.MAX_VALUE : getConfig().getTimeout());
|
setTokenValue(tokenValue, cookieTimeout);
|
||||||
SaTokenManager.getSaTokenCookie().addCookie(SaTokenManager.getSaTokenServlet().getResponse(), getTokenName(), tokenValue,
|
|
||||||
"/", getConfig().getCookieDomain(), cookieTimeout);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 返回这个token对应的专属session
|
// 返回这个token对应的专属session
|
||||||
@@ -1092,7 +1109,7 @@ public class StpLogic {
|
|||||||
* @return key
|
* @return key
|
||||||
*/
|
*/
|
||||||
public String splicingKeySwitch() {
|
public String splicingKeySwitch() {
|
||||||
return SaTokenConsts.SWITCH_TO_SAVE_KEY + getLoginKey();
|
return SaTokenConsts.SWITCH_TO_SAVE_KEY + loginKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1100,7 +1117,7 @@ public class StpLogic {
|
|||||||
* @return key
|
* @return key
|
||||||
*/
|
*/
|
||||||
public String splicingKeyJustCreatedSave() {
|
public String splicingKeyJustCreatedSave() {
|
||||||
return SaTokenConsts.JUST_CREATED_SAVE_KEY + getLoginKey();
|
return SaTokenConsts.JUST_CREATED_SAVE_KEY + loginKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,14 @@ public class StpUtil {
|
|||||||
return stpLogic.getTokenName();
|
return stpLogic.getTokenName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在当前会话写入当前tokenValue
|
||||||
|
* @param tokenValue token值
|
||||||
|
*/
|
||||||
|
public static void setTokenValue(String tokenValue, int cookieTimeout){
|
||||||
|
stpLogic.setTokenValue(tokenValue, cookieTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前tokenValue
|
* 获取当前tokenValue
|
||||||
* @return 当前tokenValue
|
* @return 当前tokenValue
|
||||||
|
|||||||
@@ -248,6 +248,7 @@ public class TestController {
|
|||||||
// .setIsLastingCookie(true) // 是否为持久Cookie(临时Cookie在浏览器关闭时会自动删除,持久Cookie在重新打开后依然存在)
|
// .setIsLastingCookie(true) // 是否为持久Cookie(临时Cookie在浏览器关闭时会自动删除,持久Cookie在重新打开后依然存在)
|
||||||
// .setTimeout(60 * 60 * 24 * 7) // 指定此次登录token的有效期, 单位:秒 (如未指定,自动取全局配置的timeout值)
|
// .setTimeout(60 * 60 * 24 * 7) // 指定此次登录token的有效期, 单位:秒 (如未指定,自动取全局配置的timeout值)
|
||||||
// );
|
// );
|
||||||
|
StpUtil.getTokenSession();
|
||||||
return AjaxJson.getSuccess("访问成功");
|
return AjaxJson.getSuccess("访问成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ spring:
|
|||||||
token-style: uuid
|
token-style: uuid
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# redis配置
|
# redis配置
|
||||||
redis:
|
redis:
|
||||||
# Redis数据库索引(默认为0)
|
# Redis数据库索引(默认为0)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
- SpringBoot2.0、Redis、Jackson、Hutool、jwt
|
- SpringBoot2.0、Redis、Jackson、Hutool、jwt
|
||||||
- SpringBoot自定义starter、Spring包扫码 + 依赖注入、AOP注解切面、yml配置映射、拦截器
|
- SpringBoot自定义starter、Spring包扫码 + 依赖注入、AOP注解切面、yml配置映射、拦截器
|
||||||
- Java8 接口与default实现、静态方法、枚举、定时器、异常类、泛型、反射、IO流、自定义注解、Lambda表达式、函数式编程
|
- Java8 接口与default实现、静态方法、枚举、定时器、异常类、泛型、反射、IO流、自定义注解、Lambda表达式、函数式编程
|
||||||
- package-info注释、Serializable序列化接口、
|
- package-info注释、Serializable序列化接口、synchronized锁
|
||||||
- java加密算法:MD5、SHA1、SHA256、AES、RSA
|
- java加密算法:MD5、SHA1、SHA256、AES、RSA
|
||||||
- OAuth2.0、同域单点登录、集群与分布式、路由Ant匹配
|
- OAuth2.0、同域单点登录、集群与分布式、路由Ant匹配
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
再往底了说,就是每个账号都会拥有一个权限码集合,我来验证这个集合中是否包含指定的权限码 <br/>
|
再往底了说,就是每个账号都会拥有一个权限码集合,我来验证这个集合中是否包含指定的权限码 <br/>
|
||||||
例如:当前账号拥有权限码集合:`["user:add", "user:delete", "user:get"]`,这时候我来验证权限 `"user:update"`,则其结果就是:**验证失败,禁止访问**
|
例如:当前账号拥有权限码集合:`["user:add", "user:delete", "user:get"]`,这时候我来验证权限 `"user:update"`,则其结果就是:**验证失败,禁止访问**
|
||||||
|
(注意: 冒号无特殊含义,可有可无)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
@@ -44,11 +44,11 @@
|
|||||||
``` java
|
``` java
|
||||||
// 底层的 StpLogic 对象
|
// 底层的 StpLogic 对象
|
||||||
public static StpLogic stpLogic = new StpLogic("user") {
|
public static StpLogic stpLogic = new StpLogic("user") {
|
||||||
// 重写 `getTokenName` 函数,返回一个与 `StpUtil` 不同的token名称, 防止冲突
|
// 重写 `splicingKeyTokenName` 函数,返回一个与 `StpUtil` 不同的token名称, 防止冲突
|
||||||
@Override
|
@Override
|
||||||
public String getTokenName() {
|
public String splicingKeyTokenName() {
|
||||||
return super.getKeyTokenName() + "-user";
|
return super.splicingKeyTokenName()+"-user";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -81,3 +81,16 @@ session.logout(); // 注销此Session会话 (从持久
|
|||||||
具体可参考`javax.servlet.http.HttpSession`,`SaSession`所含方法与其大体类似
|
具体可参考`javax.servlet.http.HttpSession`,`SaSession`所含方法与其大体类似
|
||||||
|
|
||||||
|
|
||||||
|
### Session环境隔离说明
|
||||||
|
在springboot环境下取得的session环境和通过StpUtil获取的session环境并不相通, 示例
|
||||||
|
``` java
|
||||||
|
@PostMapping("/resetPoints")
|
||||||
|
public void reset(HttpSession session) {
|
||||||
|
session.setAttribute("pointsKey", 66);
|
||||||
|
SaSession session2 = StpUtil.getSession();
|
||||||
|
Object value = session2.getAttribute("pointsKey");
|
||||||
|
System.out.println(value)
|
||||||
|
// 输出null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
而且, 在使用sa-token多账号模式下, 不同的StpUtil获取的session之间也是环境隔离
|
||||||
Reference in New Issue
Block a user