mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-04-30 04:45:51 +08:00
重构
This commit is contained in:
parent
9a2e14d147
commit
79d7967e0d
@ -23,21 +23,21 @@ import cn.dev33.satoken.util.SaFoxUtil;
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaTokenManager {
|
||||
public class SaManager {
|
||||
|
||||
/**
|
||||
* 配置文件 Bean
|
||||
*/
|
||||
private static SaTokenConfig config;
|
||||
public static void setConfig(SaTokenConfig config) {
|
||||
SaTokenManager.config = config;
|
||||
SaManager.config = config;
|
||||
if(config.getIsV()) {
|
||||
SaFoxUtil.printSaToken();
|
||||
}
|
||||
}
|
||||
public static SaTokenConfig getConfig() {
|
||||
if (config == null) {
|
||||
synchronized (SaTokenManager.class) {
|
||||
synchronized (SaManager.class) {
|
||||
if (config == null) {
|
||||
setConfig(SaTokenConfigFactory.createConfig());
|
||||
}
|
||||
@ -51,14 +51,14 @@ public class SaTokenManager {
|
||||
*/
|
||||
private static SaTokenDao saTokenDao;
|
||||
public static void setSaTokenDao(SaTokenDao saTokenDao) {
|
||||
if(SaTokenManager.saTokenDao != null && (SaTokenManager.saTokenDao instanceof SaTokenDaoDefaultImpl)) {
|
||||
((SaTokenDaoDefaultImpl)SaTokenManager.saTokenDao).endRefreshThread();
|
||||
if(SaManager.saTokenDao != null && (SaManager.saTokenDao instanceof SaTokenDaoDefaultImpl)) {
|
||||
((SaTokenDaoDefaultImpl)SaManager.saTokenDao).endRefreshThread();
|
||||
}
|
||||
SaTokenManager.saTokenDao = saTokenDao;
|
||||
SaManager.saTokenDao = saTokenDao;
|
||||
}
|
||||
public static SaTokenDao getSaTokenDao() {
|
||||
if (saTokenDao == null) {
|
||||
synchronized (SaTokenManager.class) {
|
||||
synchronized (SaManager.class) {
|
||||
if (saTokenDao == null) {
|
||||
setSaTokenDao(new SaTokenDaoDefaultImpl());
|
||||
}
|
||||
@ -72,11 +72,11 @@ public class SaTokenManager {
|
||||
*/
|
||||
private static StpInterface stpInterface;
|
||||
public static void setStpInterface(StpInterface stpInterface) {
|
||||
SaTokenManager.stpInterface = stpInterface;
|
||||
SaManager.stpInterface = stpInterface;
|
||||
}
|
||||
public static StpInterface getStpInterface() {
|
||||
if (stpInterface == null) {
|
||||
synchronized (SaTokenManager.class) {
|
||||
synchronized (SaManager.class) {
|
||||
if (stpInterface == null) {
|
||||
setStpInterface(new StpInterfaceDefaultImpl());
|
||||
}
|
||||
@ -90,11 +90,11 @@ public class SaTokenManager {
|
||||
*/
|
||||
private static SaTokenAction saTokenAction;
|
||||
public static void setSaTokenAction(SaTokenAction saTokenAction) {
|
||||
SaTokenManager.saTokenAction = saTokenAction;
|
||||
SaManager.saTokenAction = saTokenAction;
|
||||
}
|
||||
public static SaTokenAction getSaTokenAction() {
|
||||
if (saTokenAction == null) {
|
||||
synchronized (SaTokenManager.class) {
|
||||
synchronized (SaManager.class) {
|
||||
if (saTokenAction == null) {
|
||||
setSaTokenAction(new SaTokenActionDefaultImpl());
|
||||
}
|
||||
@ -108,11 +108,11 @@ public class SaTokenManager {
|
||||
*/
|
||||
private static SaTokenContext saTokenContext;
|
||||
public static void setSaTokenContext(SaTokenContext saTokenContext) {
|
||||
SaTokenManager.saTokenContext = saTokenContext;
|
||||
SaManager.saTokenContext = saTokenContext;
|
||||
}
|
||||
public static SaTokenContext getSaTokenContext() {
|
||||
if (saTokenContext == null) {
|
||||
synchronized (SaTokenManager.class) {
|
||||
synchronized (SaManager.class) {
|
||||
if (saTokenContext == null) {
|
||||
setSaTokenContext(new SaTokenContextDefaultImpl());
|
||||
}
|
||||
@ -126,11 +126,11 @@ public class SaTokenManager {
|
||||
*/
|
||||
private static SaTokenListener saTokenListener;
|
||||
public static void setSaTokenListener(SaTokenListener saTokenListener) {
|
||||
SaTokenManager.saTokenListener = saTokenListener;
|
||||
SaManager.saTokenListener = saTokenListener;
|
||||
}
|
||||
public static SaTokenListener getSaTokenListener() {
|
||||
if (saTokenListener == null) {
|
||||
synchronized (SaTokenManager.class) {
|
||||
synchronized (SaManager.class) {
|
||||
if (saTokenListener == null) {
|
||||
setSaTokenListener(new SaTokenListenerDefaultImpl());
|
||||
}
|
@ -3,7 +3,7 @@ package cn.dev33.satoken.action;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
import cn.dev33.satoken.util.SaTokenConsts;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
@ -21,7 +21,7 @@ public class SaTokenActionDefaultImpl implements SaTokenAction {
|
||||
@Override
|
||||
public String createToken(Object loginId, String loginKey) {
|
||||
// 根据配置的tokenStyle生成不同风格的token
|
||||
String tokenStyle = SaTokenManager.getConfig().getTokenStyle();
|
||||
String tokenStyle = SaManager.getConfig().getTokenStyle();
|
||||
// uuid
|
||||
if(SaTokenConsts.TOKEN_STYLE_UUID.equals(tokenStyle)) {
|
||||
return UUID.randomUUID().toString();
|
||||
|
@ -0,0 +1,42 @@
|
||||
package cn.dev33.satoken.context;
|
||||
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
import cn.dev33.satoken.context.model.SaResponse;
|
||||
import cn.dev33.satoken.context.model.SaStorage;
|
||||
|
||||
/**
|
||||
* Sa-Token 上下文持有类
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaHolder {
|
||||
|
||||
/**
|
||||
* 获取当前请求的 [Request] 对象
|
||||
*
|
||||
* @return see note
|
||||
*/
|
||||
public static SaRequest getRequest() {
|
||||
return SaManager.getSaTokenContext().getRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前请求的 [Response] 对象
|
||||
*
|
||||
* @return see note
|
||||
*/
|
||||
public static SaResponse getResponse() {
|
||||
return SaManager.getSaTokenContext().getResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前请求的 [存储器] 对象
|
||||
*
|
||||
* @return see note
|
||||
*/
|
||||
public static SaStorage getStorage() {
|
||||
return SaManager.getSaTokenContext().getStorage();
|
||||
}
|
||||
|
||||
}
|
@ -35,9 +35,15 @@ public interface SaRequest {
|
||||
public String getCookieValue(String name);
|
||||
|
||||
/**
|
||||
* 返回当前请求的URL
|
||||
* 返回当前请求path (不包括上下文名称)
|
||||
* @return see note
|
||||
*/
|
||||
public String getRequestURI();
|
||||
public String getRequestPath();
|
||||
|
||||
/**
|
||||
* 返回当前请求的类型
|
||||
* @return see note
|
||||
*/
|
||||
public String getMethod();
|
||||
|
||||
}
|
||||
|
@ -29,4 +29,21 @@ public interface SaResponse {
|
||||
*/
|
||||
public void addCookie(String name, String value, String path, String domain, int timeout);
|
||||
|
||||
/**
|
||||
* 在响应头里写入一个值
|
||||
* @param name 名字
|
||||
* @param value 值
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaResponse setHeader(String name, String value);
|
||||
|
||||
/**
|
||||
* 在响应头写入 [Server] 服务器名称
|
||||
* @param value 服务器名称
|
||||
* @return 对象自身
|
||||
*/
|
||||
public default SaResponse setServer(String value) {
|
||||
return this.setHeader("Server", value);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
/**
|
||||
@ -189,7 +189,7 @@ public class SaTokenDaoDefaultImpl implements SaTokenDao {
|
||||
public void initRefreshThread() {
|
||||
|
||||
// 如果配置了<=0的值,则不启动定时清理
|
||||
if(SaTokenManager.getConfig().getDataRefreshPeriod() <= 0) {
|
||||
if(SaManager.getConfig().getDataRefreshPeriod() <= 0) {
|
||||
return;
|
||||
}
|
||||
// 启动定时刷新
|
||||
@ -208,7 +208,7 @@ public class SaTokenDaoDefaultImpl implements SaTokenDao {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 休眠N秒
|
||||
int dataRefreshPeriod = SaTokenManager.getConfig().getDataRefreshPeriod();
|
||||
int dataRefreshPeriod = SaManager.getConfig().getDataRefreshPeriod();
|
||||
if(dataRefreshPeriod <= 0) {
|
||||
dataRefreshPeriod = 1;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package cn.dev33.satoken.listener;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.stp.SaLoginModel;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
@ -88,7 +88,7 @@ public class SaTokenListenerDefaultImpl implements SaTokenListener {
|
||||
* @param str 字符串
|
||||
*/
|
||||
public void println(String str) {
|
||||
if(SaTokenManager.getConfig().getIsLog()) {
|
||||
if(SaManager.getConfig().getIsLog()) {
|
||||
System.out.println(LOG_PREFIX + str);
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,8 @@ package cn.dev33.satoken.router;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.fun.IsRunFunction;
|
||||
import cn.dev33.satoken.fun.SaFunction;
|
||||
|
||||
@ -23,7 +24,7 @@ public class SaRouterUtil {
|
||||
* @return 是否匹配成功
|
||||
*/
|
||||
public static boolean isMatch(String pattern, String path) {
|
||||
return SaTokenManager.getSaTokenContext().matchPath(pattern, path);
|
||||
return SaManager.getSaTokenContext().matchPath(pattern, path);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,7 +48,7 @@ public class SaRouterUtil {
|
||||
* @return 是否匹配成功
|
||||
*/
|
||||
public static boolean isMatchCurrURI(String pattern) {
|
||||
return isMatch(pattern, SaTokenManager.getSaTokenContext().getRequest().getRequestURI());
|
||||
return isMatch(pattern, SaHolder.getRequest().getRequestPath());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -56,7 +57,7 @@ public class SaRouterUtil {
|
||||
* @return 是否匹配成功
|
||||
*/
|
||||
public static boolean isMatchCurrURI(List<String> patterns) {
|
||||
return isMatch(patterns, SaTokenManager.getSaTokenContext().getRequest().getRequestURI());
|
||||
return isMatch(patterns, SaHolder.getRequest().getRequestPath());
|
||||
}
|
||||
|
||||
|
||||
@ -119,7 +120,7 @@ public class SaRouterUtil {
|
||||
* @return 匹配结果包装对象
|
||||
*/
|
||||
public static IsRunFunction match(String... patterns) {
|
||||
boolean matchResult = isMatch(Arrays.asList(patterns), SaTokenManager.getSaTokenContext().getRequest().getRequestURI());
|
||||
boolean matchResult = isMatch(Arrays.asList(patterns), SaHolder.getRequest().getRequestPath());
|
||||
return new IsRunFunction(matchResult);
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ import java.util.Set;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.SaManager;
|
||||
|
||||
/**
|
||||
* Session Model
|
||||
@ -45,7 +45,7 @@ public class SaSession implements Serializable {
|
||||
this.id = id;
|
||||
this.createTime = System.currentTimeMillis();
|
||||
// $$ 通知监听器
|
||||
SaTokenManager.getSaTokenListener().doCreateSession(id);
|
||||
SaManager.getSaTokenListener().doCreateSession(id);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -246,14 +246,14 @@ public class SaSession implements Serializable {
|
||||
* 更新Session(从持久库更新刷新一下)
|
||||
*/
|
||||
public void update() {
|
||||
SaTokenManager.getSaTokenDao().updateSession(this);
|
||||
SaManager.getSaTokenDao().updateSession(this);
|
||||
}
|
||||
|
||||
/** 注销Session (从持久库删除) */
|
||||
public void logout() {
|
||||
SaTokenManager.getSaTokenDao().deleteSession(this.id);
|
||||
SaManager.getSaTokenDao().deleteSession(this.id);
|
||||
// $$ 通知监听器
|
||||
SaTokenManager.getSaTokenListener().doLogoutSession(id);
|
||||
SaManager.getSaTokenListener().doLogoutSession(id);
|
||||
}
|
||||
|
||||
/** 当Session上的tokenSign数量为零时,注销会话 */
|
||||
@ -268,7 +268,7 @@ public class SaSession implements Serializable {
|
||||
* @return 此Session的剩余存活时间 (单位: 秒)
|
||||
*/
|
||||
public long getTimeout() {
|
||||
return SaTokenManager.getSaTokenDao().getSessionTimeout(this.id);
|
||||
return SaManager.getSaTokenDao().getSessionTimeout(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -276,7 +276,7 @@ public class SaSession implements Serializable {
|
||||
* @param timeout 过期时间 (单位: 秒)
|
||||
*/
|
||||
public void updateTimeout(long timeout) {
|
||||
SaTokenManager.getSaTokenDao().updateSessionTimeout(this.id, timeout);
|
||||
SaManager.getSaTokenDao().updateSessionTimeout(this.id, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -285,7 +285,7 @@ public class SaSession implements Serializable {
|
||||
*/
|
||||
public void updateMinTimeout(long minTimeout) {
|
||||
if(getTimeout() < minTimeout) {
|
||||
SaTokenManager.getSaTokenDao().updateSessionTimeout(this.id, minTimeout);
|
||||
SaManager.getSaTokenDao().updateSessionTimeout(this.id, minTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
@ -295,7 +295,7 @@ public class SaSession implements Serializable {
|
||||
*/
|
||||
public void updateMaxTimeout(long maxTimeout) {
|
||||
if(getTimeout() > maxTimeout) {
|
||||
SaTokenManager.getSaTokenDao().updateSessionTimeout(this.id, maxTimeout);
|
||||
SaManager.getSaTokenDao().updateSessionTimeout(this.id, maxTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
package cn.dev33.satoken.session;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.SaManager;
|
||||
|
||||
/**
|
||||
* 自定义Session工具类
|
||||
@ -22,7 +22,7 @@ public class SaSessionCustomUtil {
|
||||
* @return sessionId
|
||||
*/
|
||||
public static String splicingSessionKey(String sessionId) {
|
||||
return SaTokenManager.getConfig().getTokenName() + ":" + sessionKey + ":session:" + sessionId;
|
||||
return SaManager.getConfig().getTokenName() + ":" + sessionKey + ":session:" + sessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -32,7 +32,7 @@ public class SaSessionCustomUtil {
|
||||
* @return 是否存在
|
||||
*/
|
||||
public static boolean isExists(String sessionId) {
|
||||
return SaTokenManager.getSaTokenDao().getSession(splicingSessionKey(sessionId)) != null;
|
||||
return SaManager.getSaTokenDao().getSession(splicingSessionKey(sessionId)) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -43,10 +43,10 @@ public class SaSessionCustomUtil {
|
||||
* @return SaSession
|
||||
*/
|
||||
public static SaSession getSessionById(String sessionId, boolean isCreate) {
|
||||
SaSession session = SaTokenManager.getSaTokenDao().getSession(splicingSessionKey(sessionId));
|
||||
SaSession session = SaManager.getSaTokenDao().getSession(splicingSessionKey(sessionId));
|
||||
if (session == null && isCreate) {
|
||||
session = SaTokenManager.getSaTokenAction().createSession(sessionId);
|
||||
SaTokenManager.getSaTokenDao().setSession(session, SaTokenManager.getConfig().getTimeout());
|
||||
session = SaManager.getSaTokenAction().createSession(sessionId);
|
||||
SaManager.getSaTokenDao().setSession(session, SaManager.getConfig().getTimeout());
|
||||
}
|
||||
return session;
|
||||
}
|
||||
@ -67,7 +67,7 @@ public class SaSessionCustomUtil {
|
||||
* @param sessionId 指定key
|
||||
*/
|
||||
public static void deleteSessionById(String sessionId) {
|
||||
SaTokenManager.getSaTokenDao().deleteSession(splicingSessionKey(sessionId));
|
||||
SaManager.getSaTokenDao().deleteSession(splicingSessionKey(sessionId));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package cn.dev33.satoken.stp;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.config.SaTokenConfig;
|
||||
import cn.dev33.satoken.dao.SaTokenDao;
|
||||
import cn.dev33.satoken.util.SaTokenConsts;
|
||||
@ -97,7 +97,7 @@ public class SaLoginModel {
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaLoginModel build() {
|
||||
return build(SaTokenManager.getConfig());
|
||||
return build(SaManager.getConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,12 +6,13 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.annotation.SaCheckRole;
|
||||
import cn.dev33.satoken.annotation.SaMode;
|
||||
import cn.dev33.satoken.config.SaTokenConfig;
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
import cn.dev33.satoken.context.model.SaResponse;
|
||||
import cn.dev33.satoken.context.model.SaStorage;
|
||||
@ -46,7 +47,7 @@ public class StpLogic {
|
||||
public StpLogic(String loginKey) {
|
||||
this.loginKey = loginKey;
|
||||
// 在 SaTokenManager 中记录下此 StpLogic,以便根据 LoginKey 进行查找此对象
|
||||
SaTokenManager.putStpLogic(this);
|
||||
SaManager.putStpLogic(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,7 +85,7 @@ public class StpLogic {
|
||||
* @return 生成的tokenValue
|
||||
*/
|
||||
public String createTokenValue(Object loginId) {
|
||||
return SaTokenManager.getSaTokenAction().createToken(loginId, loginKey);
|
||||
return SaManager.getSaTokenAction().createToken(loginId, loginKey);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,7 +96,7 @@ public class StpLogic {
|
||||
public void setTokenValue(String tokenValue, int cookieTimeout){
|
||||
SaTokenConfig config = getConfig();
|
||||
// 将token保存到[存储器]里
|
||||
SaStorage storage = SaTokenManager.getSaTokenContext().getStorage();
|
||||
SaStorage storage = SaHolder.getStorage();
|
||||
// 判断是否配置了token前缀
|
||||
String tokenPrefix = config.getTokenPrefix();
|
||||
if(SaFoxUtil.isEmpty(tokenPrefix)) {
|
||||
@ -107,7 +108,7 @@ public class StpLogic {
|
||||
|
||||
// 注入Cookie
|
||||
if(config.getIsReadCookie() == true){
|
||||
SaResponse response = SaTokenManager.getSaTokenContext().getResponse();
|
||||
SaResponse response = SaHolder.getResponse();
|
||||
response.addCookie(getTokenName(), tokenValue, "/", config.getCookieDomain(), cookieTimeout);
|
||||
}
|
||||
}
|
||||
@ -118,8 +119,8 @@ public class StpLogic {
|
||||
*/
|
||||
public String getTokenValue(){
|
||||
// 0. 获取相应对象
|
||||
SaStorage storage = SaTokenManager.getSaTokenContext().getStorage();
|
||||
SaRequest request = SaTokenManager.getSaTokenContext().getRequest();
|
||||
SaStorage storage = SaHolder.getStorage();
|
||||
SaRequest request = SaHolder.getRequest();
|
||||
SaTokenConfig config = getConfig();
|
||||
String keyTokenName = getTokenName();
|
||||
String tokenValue = null;
|
||||
@ -220,7 +221,7 @@ public class StpLogic {
|
||||
|
||||
// ------ 1、获取相应对象
|
||||
SaTokenConfig config = getConfig();
|
||||
SaTokenDao dao = SaTokenManager.getSaTokenDao();
|
||||
SaTokenDao dao = SaManager.getSaTokenDao();
|
||||
loginModel.build(config);
|
||||
|
||||
// ------ 2、生成一个token
|
||||
@ -246,7 +247,7 @@ public class StpLogic {
|
||||
// 3. 清理user-session上的token签名记录
|
||||
session.removeTokenSign(tokenSign.getValue());
|
||||
// $$ 通知监听器
|
||||
SaTokenManager.getSaTokenListener().doReplaced(loginKey, loginId, tokenSign.getValue(), tokenSign.getDevice());
|
||||
SaManager.getSaTokenListener().doReplaced(loginKey, loginId, tokenSign.getValue(), tokenSign.getDevice());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -277,7 +278,7 @@ public class StpLogic {
|
||||
setTokenValue(tokenValue, loginModel.getCookieTimeout());
|
||||
|
||||
// $$ 通知监听器
|
||||
SaTokenManager.getSaTokenListener().doLogin(loginKey, loginId, loginModel);
|
||||
SaManager.getSaTokenListener().doLogin(loginKey, loginId, loginModel);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -291,7 +292,7 @@ public class StpLogic {
|
||||
}
|
||||
// 如果打开了cookie模式,第一步,先把cookie清除掉
|
||||
if(getConfig().getIsReadCookie() == true){
|
||||
SaTokenManager.getSaTokenContext().getResponse().deleteCookie(getTokenName());
|
||||
SaHolder.getResponse().deleteCookie(getTokenName());
|
||||
}
|
||||
logoutByTokenValue(tokenValue);
|
||||
}
|
||||
@ -303,28 +304,28 @@ public class StpLogic {
|
||||
public void logoutByTokenValue(String tokenValue) {
|
||||
// 1. 清理掉[token-最后操作时间]
|
||||
clearLastActivity(tokenValue);
|
||||
|
||||
// 2. 清理Token-Session
|
||||
SaManager.getSaTokenDao().delete(splicingKeyTokenSession(tokenValue));
|
||||
|
||||
// 2. 尝试清除token-id键值对 (先从db中获取loginId值,如果根本查不到loginId,那么无需继续操作 )
|
||||
// 3. 尝试清除token-id键值对 (先从db中获取loginId值,如果根本查不到loginId,那么无需继续操作 )
|
||||
String loginId = getLoginIdNotHandle(tokenValue);
|
||||
if(loginId == null || NotLoginException.ABNORMAL_LIST.contains(loginId)) {
|
||||
return;
|
||||
}
|
||||
SaTokenManager.getSaTokenDao().delete(splicingKeyTokenValue(tokenValue));
|
||||
SaManager.getSaTokenDao().delete(splicingKeyTokenValue(tokenValue));
|
||||
|
||||
// $$ 通知监听器
|
||||
SaTokenManager.getSaTokenListener().doLogout(loginKey, loginId, tokenValue);
|
||||
SaManager.getSaTokenListener().doLogout(loginKey, loginId, tokenValue);
|
||||
|
||||
// 清理token-session
|
||||
SaTokenManager.getSaTokenDao().delete(splicingKeyTokenSession(tokenValue));
|
||||
|
||||
// 3. 尝试清理账号session上的token签名 (如果为null或已被标记为异常, 那么无需继续执行 )
|
||||
// 4. 尝试清理User-Session上的token签名 (如果为null或已被标记为异常, 那么无需继续执行 )
|
||||
SaSession session = getSessionByLoginId(loginId, false);
|
||||
if(session == null) {
|
||||
return;
|
||||
}
|
||||
session.removeTokenSign(tokenValue);
|
||||
|
||||
// 4. 尝试注销session
|
||||
// 5. 尝试注销User-Session
|
||||
session.logoutByTokenSignCountToZero();
|
||||
}
|
||||
|
||||
@ -359,11 +360,11 @@ public class StpLogic {
|
||||
// 2. 清理掉[token-最后操作时间]
|
||||
clearLastActivity(tokenValue);
|
||||
// 3. 标记:已被踢下线
|
||||
SaTokenManager.getSaTokenDao().update(splicingKeyTokenValue(tokenValue), NotLoginException.KICK_OUT);
|
||||
SaManager.getSaTokenDao().update(splicingKeyTokenValue(tokenValue), NotLoginException.KICK_OUT);
|
||||
// 4. 清理账号session上的token签名
|
||||
session.removeTokenSign(tokenValue);
|
||||
// $$ 通知监听器
|
||||
SaTokenManager.getSaTokenListener().doLogoutByLoginId(loginKey, loginId, tokenValue, tokenSign.getDevice());
|
||||
SaManager.getSaTokenListener().doLogoutByLoginId(loginKey, loginId, tokenValue, tokenSign.getDevice());
|
||||
}
|
||||
}
|
||||
// 3. 尝试注销session
|
||||
@ -378,10 +379,10 @@ public class StpLogic {
|
||||
*/
|
||||
public void disable(Object loginId, long disableTime) {
|
||||
// 标注为已被封禁
|
||||
SaTokenManager.getSaTokenDao().set(splicingKeyDisable(loginId), DisableLoginException.BE_VALUE, disableTime);
|
||||
SaManager.getSaTokenDao().set(splicingKeyDisable(loginId), DisableLoginException.BE_VALUE, disableTime);
|
||||
|
||||
// $$ 通知监听器
|
||||
SaTokenManager.getSaTokenListener().doDisable(loginKey, loginId, disableTime);
|
||||
SaManager.getSaTokenListener().doDisable(loginKey, loginId, disableTime);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -390,7 +391,7 @@ public class StpLogic {
|
||||
* @return see note
|
||||
*/
|
||||
public boolean isDisable(Object loginId) {
|
||||
return SaTokenManager.getSaTokenDao().get(splicingKeyDisable(loginId)) != null;
|
||||
return SaManager.getSaTokenDao().get(splicingKeyDisable(loginId)) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -399,7 +400,7 @@ public class StpLogic {
|
||||
* @return see note
|
||||
*/
|
||||
public long getDisableTime(Object loginId) {
|
||||
return SaTokenManager.getSaTokenDao().getTimeout(splicingKeyDisable(loginId));
|
||||
return SaManager.getSaTokenDao().getTimeout(splicingKeyDisable(loginId));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -407,10 +408,10 @@ public class StpLogic {
|
||||
* @param loginId 账号id
|
||||
*/
|
||||
public void untieDisable(Object loginId) {
|
||||
SaTokenManager.getSaTokenDao().delete(splicingKeyDisable(loginId));
|
||||
SaManager.getSaTokenDao().delete(splicingKeyDisable(loginId));
|
||||
|
||||
// $$ 通知监听器
|
||||
SaTokenManager.getSaTokenListener().doUntieDisable(loginKey, loginId);
|
||||
SaManager.getSaTokenListener().doUntieDisable(loginKey, loginId);
|
||||
}
|
||||
|
||||
|
||||
@ -463,9 +464,10 @@ public class StpLogic {
|
||||
if(loginId.equals(NotLoginException.KICK_OUT)) {
|
||||
throw NotLoginException.newInstance(loginKey, NotLoginException.KICK_OUT);
|
||||
}
|
||||
// 如果配置了自动续签, 则: 检查是否已经 [临时过期],同时更新[最后操作时间]
|
||||
// 检查是否已经 [临时过期]
|
||||
checkActivityTimeout(tokenValue);
|
||||
// 如果配置了自动续签, 则: 更新[最后操作时间]
|
||||
if(getConfig().getAutoRenew()) {
|
||||
checkActivityTimeout(tokenValue);
|
||||
updateLastActivityToNow(tokenValue);
|
||||
}
|
||||
// 至此,返回loginId
|
||||
@ -567,7 +569,7 @@ public class StpLogic {
|
||||
* @return loginId
|
||||
*/
|
||||
public String getLoginIdNotHandle(String tokenValue) {
|
||||
return SaTokenManager.getSaTokenDao().get(splicingKeyTokenValue(tokenValue));
|
||||
return SaManager.getSaTokenDao().get(splicingKeyTokenValue(tokenValue));
|
||||
}
|
||||
|
||||
|
||||
@ -580,10 +582,10 @@ public class StpLogic {
|
||||
* @return session对象
|
||||
*/
|
||||
public SaSession getSessionBySessionId(String sessionId, boolean isCreate) {
|
||||
SaSession session = SaTokenManager.getSaTokenDao().getSession(sessionId);
|
||||
SaSession session = SaManager.getSaTokenDao().getSession(sessionId);
|
||||
if(session == null && isCreate) {
|
||||
session = SaTokenManager.getSaTokenAction().createSession(sessionId);
|
||||
SaTokenManager.getSaTokenDao().setSession(session, getConfig().getTimeout());
|
||||
session = SaManager.getSaTokenAction().createSession(sessionId);
|
||||
SaManager.getSaTokenDao().setSession(session, getConfig().getTimeout());
|
||||
}
|
||||
return session;
|
||||
}
|
||||
@ -702,7 +704,7 @@ public class StpLogic {
|
||||
return;
|
||||
}
|
||||
// 将[最后操作时间]标记为当前时间戳
|
||||
SaTokenManager.getSaTokenDao().set(splicingKeyLastActivityTime(tokenValue), String.valueOf(System.currentTimeMillis()), getConfig().getTimeout());
|
||||
SaManager.getSaTokenDao().set(splicingKeyLastActivityTime(tokenValue), String.valueOf(System.currentTimeMillis()), getConfig().getTimeout());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -715,9 +717,9 @@ public class StpLogic {
|
||||
return;
|
||||
}
|
||||
// 删除[最后操作时间]
|
||||
SaTokenManager.getSaTokenDao().delete(splicingKeyLastActivityTime(tokenValue));
|
||||
SaManager.getSaTokenDao().delete(splicingKeyLastActivityTime(tokenValue));
|
||||
// 清除标记
|
||||
SaTokenManager.getSaTokenContext().getStorage().delete((SaTokenConsts.TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY));
|
||||
SaHolder.getStorage().delete((SaTokenConsts.TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -730,7 +732,7 @@ public class StpLogic {
|
||||
return;
|
||||
}
|
||||
// 如果本次请求已经有了[检查标记], 则立即返回
|
||||
SaStorage storage = SaTokenManager.getSaTokenContext().getStorage();
|
||||
SaStorage storage = SaHolder.getStorage();
|
||||
if(storage.get(SaTokenConsts.TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY) != null) {
|
||||
return;
|
||||
}
|
||||
@ -767,7 +769,7 @@ public class StpLogic {
|
||||
if(tokenValue == null || getConfig().getActivityTimeout() == SaTokenDao.NEVER_EXPIRE) {
|
||||
return;
|
||||
}
|
||||
SaTokenManager.getSaTokenDao().update(splicingKeyLastActivityTime(tokenValue), String.valueOf(System.currentTimeMillis()));
|
||||
SaManager.getSaTokenDao().update(splicingKeyLastActivityTime(tokenValue), String.valueOf(System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -787,7 +789,7 @@ public class StpLogic {
|
||||
* @return token剩余有效时间
|
||||
*/
|
||||
public long getTokenTimeout() {
|
||||
return SaTokenManager.getSaTokenDao().getTimeout(splicingKeyTokenValue(getTokenValue()));
|
||||
return SaManager.getSaTokenDao().getTimeout(splicingKeyTokenValue(getTokenValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -796,7 +798,7 @@ public class StpLogic {
|
||||
* @return token剩余有效时间
|
||||
*/
|
||||
public long getTokenTimeoutByLoginId(Object loginId) {
|
||||
return SaTokenManager.getSaTokenDao().getTimeout(splicingKeyTokenValue(getTokenValueByLoginId(loginId)));
|
||||
return SaManager.getSaTokenDao().getTimeout(splicingKeyTokenValue(getTokenValueByLoginId(loginId)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -813,7 +815,7 @@ public class StpLogic {
|
||||
* @return token剩余有效时间
|
||||
*/
|
||||
public long getSessionTimeoutByLoginId(Object loginId) {
|
||||
return SaTokenManager.getSaTokenDao().getSessionTimeout(splicingKeySession(loginId));
|
||||
return SaManager.getSaTokenDao().getSessionTimeout(splicingKeySession(loginId));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -830,7 +832,7 @@ public class StpLogic {
|
||||
* @return token剩余有效时间
|
||||
*/
|
||||
public long getTokenSessionTimeoutByTokenValue(String tokenValue) {
|
||||
return SaTokenManager.getSaTokenDao().getSessionTimeout(splicingKeyTokenSession(tokenValue));
|
||||
return SaManager.getSaTokenDao().getSessionTimeout(splicingKeyTokenSession(tokenValue));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -858,7 +860,7 @@ public class StpLogic {
|
||||
// ------ 开始查询
|
||||
// 获取相关数据
|
||||
String keyLastActivityTime = splicingKeyLastActivityTime(tokenValue);
|
||||
String lastActivityTimeString = SaTokenManager.getSaTokenDao().get(keyLastActivityTime);
|
||||
String lastActivityTimeString = SaManager.getSaTokenDao().get(keyLastActivityTime);
|
||||
// 查不到,返回-2
|
||||
if(lastActivityTimeString == null) {
|
||||
return SaTokenDao.NOT_VALUE_EXPIRE;
|
||||
@ -884,8 +886,8 @@ public class StpLogic {
|
||||
* @return 是否含有指定角色标识
|
||||
*/
|
||||
public boolean hasRole(Object loginId, String role) {
|
||||
List<String> roleList = SaTokenManager.getStpInterface().getRoleList(loginId, loginKey);
|
||||
return SaTokenManager.getSaTokenAction().hasElement(roleList, role);
|
||||
List<String> roleList = SaManager.getStpInterface().getRoleList(loginId, loginKey);
|
||||
return SaManager.getSaTokenAction().hasElement(roleList, role);
|
||||
// return !(roleList == null || roleList.contains(role) == false);
|
||||
}
|
||||
|
||||
@ -914,9 +916,9 @@ public class StpLogic {
|
||||
*/
|
||||
public void checkRoleAnd(String... roleArray){
|
||||
Object loginId = getLoginId();
|
||||
List<String> roleList = SaTokenManager.getStpInterface().getRoleList(loginId, loginKey);
|
||||
List<String> roleList = SaManager.getStpInterface().getRoleList(loginId, loginKey);
|
||||
for (String role : roleArray) {
|
||||
if(SaTokenManager.getSaTokenAction().hasElement(roleList, role) == false) {
|
||||
if(SaManager.getSaTokenAction().hasElement(roleList, role) == false) {
|
||||
throw new NotRoleException(role, this.loginKey);
|
||||
}
|
||||
}
|
||||
@ -928,9 +930,9 @@ public class StpLogic {
|
||||
*/
|
||||
public void checkRoleOr(String... roleArray){
|
||||
Object loginId = getLoginId();
|
||||
List<String> roleList = SaTokenManager.getStpInterface().getRoleList(loginId, loginKey);
|
||||
List<String> roleList = SaManager.getStpInterface().getRoleList(loginId, loginKey);
|
||||
for (String role : roleArray) {
|
||||
if(SaTokenManager.getSaTokenAction().hasElement(roleList, role) == true) {
|
||||
if(SaManager.getSaTokenAction().hasElement(roleList, role) == true) {
|
||||
// 有的话提前退出
|
||||
return;
|
||||
}
|
||||
@ -950,8 +952,8 @@ public class StpLogic {
|
||||
* @return 是否含有指定权限
|
||||
*/
|
||||
public boolean hasPermission(Object loginId, String permission) {
|
||||
List<String> permissionList = SaTokenManager.getStpInterface().getPermissionList(loginId, loginKey);
|
||||
return SaTokenManager.getSaTokenAction().hasElement(permissionList, permission);
|
||||
List<String> permissionList = SaManager.getStpInterface().getPermissionList(loginId, loginKey);
|
||||
return SaManager.getSaTokenAction().hasElement(permissionList, permission);
|
||||
// return !(permissionList == null || permissionList.contains(permission) == false);
|
||||
}
|
||||
|
||||
@ -980,9 +982,9 @@ public class StpLogic {
|
||||
*/
|
||||
public void checkPermissionAnd(String... permissionArray){
|
||||
Object loginId = getLoginId();
|
||||
List<String> permissionList = SaTokenManager.getStpInterface().getPermissionList(loginId, loginKey);
|
||||
List<String> permissionList = SaManager.getStpInterface().getPermissionList(loginId, loginKey);
|
||||
for (String permission : permissionArray) {
|
||||
if(SaTokenManager.getSaTokenAction().hasElement(permissionList, permission) == false) {
|
||||
if(SaManager.getSaTokenAction().hasElement(permissionList, permission) == false) {
|
||||
throw new NotPermissionException(permission, this.loginKey);
|
||||
}
|
||||
}
|
||||
@ -994,9 +996,9 @@ public class StpLogic {
|
||||
*/
|
||||
public void checkPermissionOr(String... permissionArray){
|
||||
Object loginId = getLoginId();
|
||||
List<String> permissionList = SaTokenManager.getStpInterface().getPermissionList(loginId, loginKey);
|
||||
List<String> permissionList = SaManager.getStpInterface().getPermissionList(loginId, loginKey);
|
||||
for (String permission : permissionArray) {
|
||||
if(SaTokenManager.getSaTokenAction().hasElement(permissionList, permission) == true) {
|
||||
if(SaManager.getSaTokenAction().hasElement(permissionList, permission) == true) {
|
||||
// 有的话提前退出
|
||||
return;
|
||||
}
|
||||
@ -1105,7 +1107,7 @@ public class StpLogic {
|
||||
* @return token集合
|
||||
*/
|
||||
public List<String> searchTokenValue(String keyword, int start, int size) {
|
||||
return SaTokenManager.getSaTokenDao().searchData(splicingKeyTokenValue(""), keyword, start, size);
|
||||
return SaManager.getSaTokenDao().searchData(splicingKeyTokenValue(""), keyword, start, size);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1116,7 +1118,7 @@ public class StpLogic {
|
||||
* @return sessionId集合
|
||||
*/
|
||||
public List<String> searchSessionId(String keyword, int start, int size) {
|
||||
return SaTokenManager.getSaTokenDao().searchData(splicingKeySession(""), keyword, start, size);
|
||||
return SaManager.getSaTokenDao().searchData(splicingKeySession(""), keyword, start, size);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1127,7 +1129,7 @@ public class StpLogic {
|
||||
* @return sessionId集合
|
||||
*/
|
||||
public List<String> searchTokenSessionId(String keyword, int start, int size) {
|
||||
return SaTokenManager.getSaTokenDao().searchData(splicingKeyTokenSession(""), keyword, start, size);
|
||||
return SaManager.getSaTokenDao().searchData(splicingKeyTokenSession(""), keyword, start, size);
|
||||
}
|
||||
|
||||
|
||||
@ -1210,7 +1212,7 @@ public class StpLogic {
|
||||
*/
|
||||
public SaTokenConfig getConfig() {
|
||||
// 为什么再次代理一层? 为某些极端业务场景下[需要不同StpLogic不同配置]提供便利
|
||||
return SaTokenManager.getConfig();
|
||||
return SaManager.getConfig();
|
||||
}
|
||||
|
||||
|
||||
@ -1282,14 +1284,14 @@ public class StpLogic {
|
||||
* @param loginId 指定loginId
|
||||
*/
|
||||
public void switchTo(Object loginId) {
|
||||
SaTokenManager.getSaTokenContext().getStorage().set(splicingKeySwitch(), loginId);
|
||||
SaHolder.getStorage().set(splicingKeySwitch(), loginId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束临时切换身份
|
||||
*/
|
||||
public void endSwitch() {
|
||||
SaTokenManager.getSaTokenContext().getStorage().delete(splicingKeySwitch());
|
||||
SaHolder.getStorage().delete(splicingKeySwitch());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1297,7 +1299,7 @@ public class StpLogic {
|
||||
* @return 是否正处于[身份临时切换]中
|
||||
*/
|
||||
public boolean isSwitch() {
|
||||
return SaTokenManager.getSaTokenContext().getStorage().get(splicingKeySwitch()) != null;
|
||||
return SaHolder.getStorage().get(splicingKeySwitch()) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1305,7 +1307,7 @@ public class StpLogic {
|
||||
* @return 返回[身份临时切换]的loginId
|
||||
*/
|
||||
public Object getSwitchLoginId() {
|
||||
return SaTokenManager.getSaTokenContext().getStorage().get(splicingKeySwitch());
|
||||
return SaHolder.getStorage().get(splicingKeySwitch());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,14 +3,14 @@ package com.pj;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.SaManager;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SaTokenJwtDemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SaTokenJwtDemoApplication.class, args);
|
||||
System.out.println("\n启动成功:sa-token配置如下:" + SaTokenManager.getConfig());
|
||||
System.out.println("\n启动成功:sa-token配置如下:" + SaManager.getConfig());
|
||||
}
|
||||
|
||||
}
|
@ -4,7 +4,7 @@ import java.util.Date;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.config.SaTokenConfig;
|
||||
import cn.dev33.satoken.context.model.SaStorage;
|
||||
import cn.dev33.satoken.dao.SaTokenDao;
|
||||
@ -124,13 +124,13 @@ public class SaTokenJwtUtil {
|
||||
@Override
|
||||
public void setLoginId(Object loginId, SaLoginModel loginModel) {
|
||||
// ------ 1、获取相应对象
|
||||
SaStorage storage = SaTokenManager.getSaTokenContext().getStorage();
|
||||
SaStorage storage = SaManager.getSaTokenContext().getStorage();
|
||||
SaTokenConfig config = getConfig();
|
||||
// ------ 2、生成一个token
|
||||
String tokenValue = createTokenValue(loginId);
|
||||
storage.set(splicingKeyJustCreatedSave(), tokenValue); // 将token保存到本次request里
|
||||
if(config.getIsReadCookie() == true){ // cookie注入
|
||||
SaTokenManager.getSaTokenContext().getResponse().addCookie(getTokenName(), tokenValue, "/", config.getCookieDomain(), (int)config.getTimeout());
|
||||
SaManager.getSaTokenContext().getResponse().addCookie(getTokenName(), tokenValue, "/", config.getCookieDomain(), (int)config.getTimeout());
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,7 +154,7 @@ public class SaTokenJwtUtil {
|
||||
}
|
||||
// 如果打开了cookie模式,把cookie清除掉
|
||||
if(getConfig().getIsReadCookie() == true){
|
||||
SaTokenManager.getSaTokenContext().getResponse().deleteCookie(getTokenName());
|
||||
SaManager.getSaTokenContext().getResponse().deleteCookie(getTokenName());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ package com.pj;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.SaManager;
|
||||
|
||||
/**
|
||||
* sa-token整合SpringBoot 示例
|
||||
@ -15,7 +15,7 @@ public class SaTokenDemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SaTokenDemoApplication.class, args);
|
||||
System.out.println("\n启动成功:sa-token配置如下:" + SaTokenManager.getConfig());
|
||||
System.out.println("\n启动成功:sa-token配置如下:" + SaManager.getConfig());
|
||||
}
|
||||
|
||||
}
|
@ -1,10 +1,16 @@
|
||||
package com.pj.satoken;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import com.pj.util.AjaxJson;
|
||||
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.filter.SaServletFilter;
|
||||
import cn.dev33.satoken.interceptor.SaAnnotationInterceptor;
|
||||
import cn.dev33.satoken.router.SaRouterUtil;
|
||||
|
||||
|
||||
/**
|
||||
@ -24,27 +30,44 @@ public class SaTokenConfigure implements WebMvcConfigurer {
|
||||
registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**").excludePathPatterns("");
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 注册 [sa-token全局过滤器]
|
||||
// */
|
||||
// @Bean
|
||||
// public SaServletFilter getSaReactorFilter() {
|
||||
// return new SaServletFilter()
|
||||
// // 指定 [拦截路由]
|
||||
// .addInclude("/**")
|
||||
// // 指定 [放行路由]
|
||||
// .addExclude("/favicon.ico")
|
||||
// // 指定[认证函数]: 每次请求执行
|
||||
// .setAuth(r -> {
|
||||
// System.out.println("---------- sa全局认证");
|
||||
// SaRouterUtil.match("/test/test", () -> StpUtil.checkLogin());
|
||||
// })
|
||||
// // 指定[异常处理函数]:每次[认证函数]发生异常时执行此函数
|
||||
// .setError(e -> {
|
||||
// System.out.println("---------- sa全局异常 ");
|
||||
// return AjaxJson.getError(e.getMessage());
|
||||
// })
|
||||
// ;
|
||||
// }
|
||||
/**
|
||||
* 注册 [sa-token全局过滤器]
|
||||
*/
|
||||
@Bean
|
||||
public SaServletFilter getSaReactorFilter() {
|
||||
return new SaServletFilter()
|
||||
|
||||
// 指定 [拦截路由] 与 [放行路由]
|
||||
.addInclude("/**").addExclude("/favicon.ico")
|
||||
|
||||
// 认证函数: 每次请求执行
|
||||
.setAuth(r -> {
|
||||
System.out.println("---------- sa全局认证");
|
||||
|
||||
SaRouterUtil.match("/test/test", () -> new Object());
|
||||
})
|
||||
|
||||
// 异常处理函数:每次认证函数发生异常时执行此函数
|
||||
.setError(e -> {
|
||||
System.out.println("---------- sa全局异常 ");
|
||||
return AjaxJson.getError(e.getMessage());
|
||||
})
|
||||
|
||||
// 前置函数:在每次认证函数之前执行
|
||||
.setBeforeAuth(r -> {
|
||||
// ---------- 设置一些安全响应头 ----------
|
||||
SaHolder.getResponse()
|
||||
// 服务器名称
|
||||
.setServer("sa-server")
|
||||
// 是否可以在iframe显示视图: DENY=不可以 | SAMEORIGIN=同域下可以 | ALLOW-FROM uri=指定域名下可以
|
||||
.setHeader("X-Frame-Options", "SAMEORIGIN")
|
||||
// 是否启用浏览器默认XSS防护: 0=禁用 | 1=启用 | 1; mode=block 启用, 并在检查到XSS攻击时,停止渲染页面
|
||||
.setHeader("X-Frame-Options", "1; mode=block")
|
||||
// 禁用浏览器内容嗅探
|
||||
.setHeader("X-Content-Type-Options", "nosniff")
|
||||
;
|
||||
})
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ spring:
|
||||
# 是否输出操作日志
|
||||
is-log: false
|
||||
|
||||
|
||||
# redis配置
|
||||
redis:
|
||||
# Redis数据库索引(默认为0)
|
||||
@ -44,4 +43,12 @@ spring:
|
||||
# 连接池中的最小空闲连接
|
||||
min-idle: 0
|
||||
|
||||
|
||||
|
||||
# 静态文件路径映射
|
||||
resources:
|
||||
static-locations: file:E:\work\project-yun\sa-admin
|
||||
|
||||
|
||||
|
||||
|
@ -14,7 +14,7 @@ package com.pj;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.SaManager;
|
||||
|
||||
/**
|
||||
* sa-token整合webflux 示例
|
||||
@ -26,7 +26,7 @@ public class SaTokenWebfluxDemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SaTokenWebfluxDemoApplication.class, args);
|
||||
System.out.println("\n启动成功:sa-token配置如下:" + SaTokenManager.getConfig());
|
||||
System.out.println("\n启动成功:sa-token配置如下:" + SaManager.getConfig());
|
||||
}
|
||||
|
||||
}
|
@ -45,6 +45,7 @@
|
||||
- [Session模型详解](/fun/session-model)
|
||||
- [TokenInfo参数详解](/fun/token-info)
|
||||
- [框架源码所有技术栈](/fun/tech-stack)
|
||||
- [Web开发常见漏洞防护](/fun/web-loophole)
|
||||
<!-- - [Sa-Token大事记](/fun/timeline) -->
|
||||
|
||||
|
||||
|
112
sa-token-doc/doc/fun/web-loophole.md
Normal file
112
sa-token-doc/doc/fun/web-loophole.md
Normal file
@ -0,0 +1,112 @@
|
||||
# Web开发常见漏洞防护
|
||||
本章介绍web开发时常见漏洞的防护方法
|
||||
|
||||
|
||||
### 点击劫持
|
||||
|
||||
简而言之,点击劫持就是攻击者会自己搭建一个网页,这个网页分为两层:
|
||||
- 上层是被iframe导入的被攻击网站,具有一些敏感性操作,比如转账、点赞等按钮,这一层会完全透明
|
||||
- 下层是攻击者自己精心制作的网页,它会准备一个按钮诱导你进行点击(比如点击领取红包等),当你点击这个按钮时,响应你的将不会是这个按钮,而是上层的转账页面,在不知情的情况下造成财产损失
|
||||
|
||||
详情介绍参考:[https://blog.csdn.net/qq_32523587/article/details/79613768](https://blog.csdn.net/qq_32523587/article/details/79613768)
|
||||
|
||||
防范点击劫持的最有效做法就是增加响应头:`X-Frame-Options: DENY`, 告诉浏览器我们的网站不可以通过 iframe 进行展示(浏览器收到此响应头的指示之后,会拒绝渲染页面),
|
||||
从根本上杜绝了点击劫持发生的可能,在 [全局过滤器](/use/global-filter) 章节的示例中,我们已经展示了如何在过滤器中增加安全响应头
|
||||
|
||||
响应头`X-Frame-Options`有三个取值:
|
||||
- `DENY`: 任何时候都不可以通过 iframe 展示视图
|
||||
- `SAMEORIGIN`: 在同域下可以通过 iframe 展示视图
|
||||
- `ALLOW-FROM uri`: 指定地址来源的访问下可以通过 iframe 展示视图
|
||||
|
||||
除了后端的响应头,我们还可以在前端使用如下方式进行判断:
|
||||
``` js
|
||||
// 判断当前页面是否在顶层视口打开
|
||||
if(top != window) {
|
||||
// 跳入一个安全页面,比如404页
|
||||
location.href="xxx";
|
||||
}
|
||||
```
|
||||
除了跳转页面,你还可以用其它方法防御点击劫持,比如加载一个全局遮罩来隔离用户的点击操作,或者在非顶层窗口下拒绝提交token,使用户保持未登录状态
|
||||
|
||||
|
||||
### XSS攻击
|
||||
|
||||
XSS(跨站脚本攻击)就是指攻击者在一段正常的内容中嵌入恶意脚本,使得访问网页的用户自动运行一些破坏性的代码
|
||||
|
||||
例如一个论坛具有发帖功能,攻击者在发帖时故意插入一段如下内容:
|
||||
``` java
|
||||
<img src="xxx" onerror="alert('xss攻击!')" />
|
||||
```
|
||||
如果论坛服务端没有对此进行任何防护,那么用户每次访问这个帖子的时候都会被强制弹窗,
|
||||
事实上真正的`XSS攻击`绝不只是弹窗骚扰一下那么简单,它可以完成窃取Cookie,自动转账等破坏性操作
|
||||
|
||||
防范XSS攻击:
|
||||
1. 首先安全响应头给安排上:`X-Frame-Options: 1; mode=block`, 这是浏览器默认提供的XSS防护机制
|
||||
2. 有条件的情况下,尽量使用前后台分离架构,传统服务端渲染视图时几乎每一个变量都可能成为XSS注入点,而前后台分离下一般只有富文本渲染才会有机会XSS注入
|
||||
3. 对所有的用户输入必须XSS过滤,特别是字符串型参数
|
||||
4. 可以使用一些自动扫描工具寻找潜在的 XSS 漏洞
|
||||
|
||||
|
||||
### CSRF攻击
|
||||
CSRF(跨站请求伪造),又称 XSRF,攻击流程如下:
|
||||
|
||||
1. 用户登陆站点`a.com`,身份令牌被写入Cookie中
|
||||
2. 攻击者搭建站点`b.com`,引诱用户访问
|
||||
3. 用户访问`b.com`时,自动执行了攻击者准备的js代码,即:调用`a.com`的转账接口
|
||||
4. 用户在不知情的情况下,造成了财产损失
|
||||
|
||||
仅仅访问一个不安全的站点就让我们造成了财产损失?事实上,真正的CSRF攻击并没有这么简单,挡在攻击者第一道门槛便是`CORS同源策略`
|
||||
|
||||
同源策略限制了js在`b.com`中只能操作`b.com`的数据(`Cookie`、`localStorage`、`DOM`等),而无法直接操作`a.com`的数据。
|
||||
|
||||
这就导致一个结果:虽然在`b.com`可以调用`a.com`的转账接口,但是却无法携带用户储存在`a.com`的授权Cookie,对于`a.com`来讲,即使收到了浏览器发来的请求,
|
||||
也因为请求中没有携带token令牌,而无法识别调用者具体是谁,只能将其视为一次无效调用。
|
||||
|
||||
但是,请注意!这个小小的限制,虽然为用户提供了安全保护,却也为我们开发者造成了不小的困扰,特别是在前后端分离架构下,我们经常会遇到这个错误:
|
||||
|
||||

|
||||
|
||||
这就是导致无数前端后端互相撕逼的 —— 跨域!
|
||||
|
||||
浏览器在检测到你身处`b.com`却想要调用`a.com`的接口时,会率先发送一个`OPTIONS`预检请求,目的是为了询问`a.com`是否同意`b.com`发起的请求,
|
||||
在默认情况下,`a.com`收到一个陌生的第三方网站发来的请求,做出的回应肯定是:`不允许`, 浏览器收到回应就识相的关闭了请求,跨域请求失败
|
||||
|
||||
但是,有些开发者为了省事,直接设置了响应头: `Access-Control-Allow-Origin: *`,允许任何第三方网站的请求,这就给`CSRF攻击`留下了可乘之机
|
||||
|
||||
假设我们设置了只允许指定的网站跨域请求,就万事大吉了吗?并没有,攻击者仍可以通过抓包等手段得到我们的转账url,
|
||||
在`b.com`里,通过`open(url)`直接打开一个新的窗口调用转账接口,由于是属于打开新页面,浏览器连`OPTIONS`预检请求都不会发送,而是直接调用接口成功
|
||||
|
||||
此招无解吗?并不。由于它是属于打开新页面,这就导致调用接口时只能发送`get请求`,我们在设计接口时只需要遵守一个准则:`敏感接口一律post,禁止get调用`即可。
|
||||
|
||||
究其原因,导致`CSRF攻击`频频发生的原因是什么?是我们在跨域请求时,浏览器总是“自作聪明”的自动提交主站`Cookie`,
|
||||
在浏览器的不断更新中,Cookie的跨域规则变得愈发复杂,新手开发者及其容易绕的晕头转向,而同时`w3c`对`Cookie`规范的各种修修补补,又总是解决一个问题的同时暴露出其他的N多问题
|
||||
|
||||
既然Cookie机制如此难以驾驭,我们何不果断的放弃Cookie机制,改用`localStorage`机制存储会话token,这种方式轻松避免了`自动提交`带来的各种安全问题。
|
||||
事实上,`localStorage存储` + `header请求头提交`也是前后台分离趋势下的常见会话处理方案
|
||||
|
||||
篇幅有限,我们总结一下防范`CSRF攻击`要点
|
||||
|
||||
**在Cookie模式下**:
|
||||
1. 仅靠`CORS同源策略`无法彻底防范`CSRF攻击`,我们必须在后台建立`第三方域名白名单`,只有在白名单中的第三方域名才可以跨域调用我们的接口
|
||||
2. 涉及到数据增删改类型的接口,必须是`post`模式(或其它),严禁`get`模式,查询接口可以`get`
|
||||
3. 敏感操作增加验证码或者二次验证密码,减小被攻击的概率
|
||||
|
||||
**在 localStorage存储 + header请求头提交 模式下**:
|
||||
1. 在配置文件中,配置`is-read-cookie: false`,关闭Cookie模式,防止Sa-Token在登录时注入Cookie
|
||||
2. 同上,敏感操作增加验证码或者二次验证密码,减小被攻击的概率
|
||||
|
||||
有关CSRF攻防讲解的比较通透的一篇文章:[https://juejin.cn/post/6844903689702866952](https://juejin.cn/post/6844903689702866952)
|
||||
|
||||
|
||||
### Token泄露
|
||||
Token泄露一般发生在客户端,比如用户连接了不安全的WiFi导致通讯被监听,虽然此情形下token泄露的责任在于用户,但是我们还是有必要采取一定的措施使其损失降到最低
|
||||
1. 有条件上https的话一律https
|
||||
2. token有效期一定不能设置为永久,而且要尽量的短(but:为了不影响用户体验又不能设置特别的短,so: 7-30天是个比较合适的范围)
|
||||
3. 对敏感操作接口,增加密码二次校验(或手机验证码等)
|
||||
4. 用户更改密码后使其历史会话直接过期
|
||||
5. 有条件的情况下后台管理增加踢人下线功能,对已经泄露token的账号可以及时清理下线
|
||||
|
||||
|
||||
<br><br>
|
||||
更多类型漏洞连载中.... (欢迎提交pr)
|
||||
|
@ -15,7 +15,7 @@
|
||||
<a href="/">
|
||||
<div class="logo-box">
|
||||
<img src="logo.png" title="logo" />
|
||||
<h1 class="logo-text">sa-token</h1>
|
||||
<h1 class="logo-text">Sa-Token</h1>
|
||||
</div>
|
||||
</a>
|
||||
<nav>
|
||||
@ -47,7 +47,7 @@
|
||||
</div>
|
||||
<script>
|
||||
var name = '<img style="width: 60px; height: 60px; vertical-align: middle;" src="logo.png" alt="logo" /> ';
|
||||
name += '<b style="font-size: 28px; vertical-align: middle;">sa-token</b> <sub>v1.17.0</sub>'
|
||||
name += '<b style="font-size: 28px; vertical-align: middle;">Sa-Token</b> <sub>v1.17.0</sub>'
|
||||
window.$docsify = {
|
||||
name: name, // 名字
|
||||
repo: 'https://github.com/dromara/sa-token', // github地址
|
||||
|
@ -82,7 +82,7 @@ body{font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu
|
||||
}
|
||||
|
||||
/* 代码行号盒子样式 */
|
||||
.code-line-box {list-style-type: none; border-right: 1px solid #000; position: absolute; top: 0; left: 0; width: 40px;}
|
||||
.code-line-box {list-style-type: none; border-right: 1px solid #000; position: absolute; top: 0; left: 0; width: 40px; user-select: none;}
|
||||
.code-line-box {padding: calc(1.5em + 1px) 0px !important; padding-bottom: calc(1.5em + 20px) !important; margin: 0px !important;}
|
||||
.code-line-box {line-height: inherit !important; background-color: #111; color: #aaa;font-weight: 400;font-size: 0.85em;text-align: center;}
|
||||
.code-line-box {font-family: source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace;}
|
||||
|
@ -7,6 +7,11 @@
|
||||
|
||||
<table class="gzh-table" style="text-align: center;">
|
||||
<tr>
|
||||
<td>
|
||||
<img src="https://mp.weixin.qq.com/mp/qrcode?scene=10000005&size=102&__biz=MzA4MDMyODg4OQ==&mid=2649482871&idx=2&sn=b376585faaf814d9072af539efda68fe&send_time="/>
|
||||
<b>大侠学JAVA</b>
|
||||
<span>道阻且长,行则将至,专注分享JAVA领域的干货</span>
|
||||
</td>
|
||||
<td>
|
||||
<img src="https://mp.weixin.qq.com/mp/qrcode?scene=10000005&size=102&__biz=Mzg2MDIxNjAzNg==&mid=2247485810&idx=1&sn=afd46d5924afbc1030a87b5d56265fdf&send_time="/>
|
||||
<b>Java大厂面试官</b>
|
||||
@ -19,7 +24,6 @@
|
||||
</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Spring WebFlux 集成 Sa-Token 示例
|
||||
|
||||
WebFlux基于Reactor响应式模型开发,有着与标准ServletAPI完全不同的底层架构,因此要适配WebFlux, 必须提供与Reactor相关的整合实现,
|
||||
本篇将以WebFlux为例,展示sa-token与Reactor响应式模型web框架相整合的示例, **你可以用同样方式去对接其它Reactor模型Web框架**
|
||||
本篇将以WebFlux为例,展示sa-token与Reactor响应式模型web框架相整合的示例, **你可以用同样方式去对接其它Reactor模型Web框架**(Netty、Soul、Gateway等)
|
||||
|
||||
整合示例在官方仓库的`/sa-token-demo-webflux`文件夹下,如遇到难点可结合源码进行测试学习
|
||||
|
||||
|
@ -35,13 +35,10 @@ public class SaTokenConfigure {
|
||||
public SaServletFilter getSaReactorFilter() {
|
||||
return new SaServletFilter()
|
||||
|
||||
// 指定 [拦截路由]
|
||||
.addInclude("/**")
|
||||
// 指定 拦截路由 与 放行路由
|
||||
.addInclude("/**").addExclude("/favicon.ico")
|
||||
|
||||
// 指定 [放行路由]
|
||||
.addExclude("/favicon.ico")
|
||||
|
||||
// 指定[认证函数]: 每次请求执行
|
||||
// 认证函数: 每次请求执行
|
||||
.setAuth(r -> {
|
||||
System.out.println("---------- 进入sa-token全局认证 -----------");
|
||||
|
||||
@ -51,11 +48,26 @@ public class SaTokenConfigure {
|
||||
// 更多拦截处理方式,请参考“路由拦截式鉴权”章节
|
||||
})
|
||||
|
||||
// 指定[异常处理函数]:每次[认证函数]发生异常时执行此函数
|
||||
// 异常处理函数:每次认证函数发生异常时执行此函数
|
||||
.setError(e -> {
|
||||
System.out.println("---------- 进入sa-token异常处理 -----------");
|
||||
return AjaxJson.getError(e.getMessage());
|
||||
})
|
||||
|
||||
// 前置函数:在每次认证函数之前执行
|
||||
.setBeforeAuth(r -> {
|
||||
// ---------- 设置一些安全响应头 ----------
|
||||
SaHolder.getResponse()
|
||||
// 服务器名称
|
||||
.setServer("sa-server")
|
||||
// 是否可以在iframe显示视图: DENY=不可以 | SAMEORIGIN=同域下可以 | ALLOW-FROM uri=指定域名下可以
|
||||
.setHeader("X-Frame-Options", "SAMEORIGIN")
|
||||
// 是否启用浏览器默认XSS防护: 0=禁用 | 1=启用 | 1; mode=block 启用, 并在检查到XSS攻击时,停止渲染页面
|
||||
.setHeader("X-Frame-Options", "1; mode=block")
|
||||
// 禁用浏览器内容嗅探
|
||||
.setHeader("X-Content-Type-Options", "nosniff")
|
||||
;
|
||||
})
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -117,6 +117,29 @@ StpUtil.checkRoleOr("super-admin", "shop-admin");
|
||||
你可以创建一个全局异常拦截器,统一返回给前端的格式,参考:[码云:GlobalException.java](https://gitee.com/dromara/sa-token/blob/master/sa-token-demo-springboot/src/main/java/com/pj/test/GlobalException.java)
|
||||
|
||||
|
||||
### 权限通配符
|
||||
Sa-Token允许你根据通配符指定泛权限,例如当一个账号拥有`user*`的权限时,`user-add`、`user-delete`、`user-update`都将匹配通过
|
||||
|
||||
``` java
|
||||
// 当拥有 user* 权限时
|
||||
StpUtil.hasPermission("user-add"); // true
|
||||
StpUtil.hasPermission("user-update"); // true
|
||||
StpUtil.hasPermission("art-add"); // false
|
||||
|
||||
// 当拥有 *-delete 权限时
|
||||
StpUtil.hasPermission("user-add"); // false
|
||||
StpUtil.hasPermission("user-delete"); // true
|
||||
StpUtil.hasPermission("art-delete"); // true
|
||||
|
||||
// 当拥有 *.js 权限时
|
||||
StpUtil.hasPermission("index.js"); // true
|
||||
StpUtil.hasPermission("index.css"); // false
|
||||
StpUtil.hasPermission("index.html"); // false
|
||||
```
|
||||
|
||||
上帝权限:当一个账号拥有 `"*"` 权限时,他可以验证通过任何权限码 (角色认证同理)
|
||||
|
||||
|
||||
### 如何把权限精确搭到按钮级?
|
||||
权限精确到按钮级的意思就是指:**权限范围可以控制到页面上的每一个按钮是否显示**
|
||||
|
||||
|
@ -5,7 +5,7 @@ import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
||||
import cn.dev33.satoken.oauth2.model.AccessTokenModel;
|
||||
@ -261,15 +261,15 @@ public interface SaOAuth2Interface {
|
||||
|
||||
// 将此授权码保存到DB
|
||||
long codeTimeout = SaOAuth2Manager.getConfig().getCodeTimeout();
|
||||
SaTokenManager.getSaTokenDao().setObject(getKeyCodeModel(code), codeModel, codeTimeout);
|
||||
SaManager.getSaTokenDao().setObject(getKeyCodeModel(code), codeModel, codeTimeout);
|
||||
|
||||
// 如果此[Client&账号]已经有code正在存储,则先删除它
|
||||
String key = getKeyClientLoginId(loginId, clientId);
|
||||
SaTokenManager.getSaTokenDao().delete(key);
|
||||
SaManager.getSaTokenDao().delete(key);
|
||||
|
||||
// 将此[Client&账号]的最新授权码保存到DB中
|
||||
// 以便于完成授权码覆盖操作: 保证每次只有最新的授权码有效
|
||||
SaTokenManager.getSaTokenDao().set(key, code, codeTimeout);
|
||||
SaManager.getSaTokenDao().set(key, code, codeTimeout);
|
||||
|
||||
// 返回
|
||||
return codeModel;
|
||||
@ -281,7 +281,7 @@ public interface SaOAuth2Interface {
|
||||
* @return 授权码Model
|
||||
*/
|
||||
public default CodeModel getCode(String code) {
|
||||
return (CodeModel)SaTokenManager.getSaTokenDao().getObject(getKeyCodeModel(code));
|
||||
return (CodeModel)SaManager.getSaTokenDao().getObject(getKeyCodeModel(code));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -290,7 +290,7 @@ public interface SaOAuth2Interface {
|
||||
* @param codeModel 授权码Model
|
||||
*/
|
||||
public default void updateCode(String code, CodeModel codeModel) {
|
||||
SaTokenManager.getSaTokenDao().updateObject(getKeyCodeModel(code), codeModel);
|
||||
SaManager.getSaTokenDao().updateObject(getKeyCodeModel(code), codeModel);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -314,7 +314,7 @@ public interface SaOAuth2Interface {
|
||||
* @param code 授权码
|
||||
*/
|
||||
public default void deleteCode(String code) {
|
||||
SaTokenManager.getSaTokenDao().deleteObject(getKeyCodeModel(code));
|
||||
SaManager.getSaTokenDao().deleteObject(getKeyCodeModel(code));
|
||||
}
|
||||
|
||||
|
||||
@ -337,10 +337,10 @@ public interface SaOAuth2Interface {
|
||||
|
||||
// 获取 TokenModel 并保存
|
||||
AccessTokenModel tokenModel = converCodeToAccessToken(codeModel);
|
||||
SaTokenManager.getSaTokenDao().setObject(getKeyAccessToken(tokenModel.getAccessToken()), tokenModel, SaOAuth2Manager.getConfig().getAccessTokenTimeout());
|
||||
SaManager.getSaTokenDao().setObject(getKeyAccessToken(tokenModel.getAccessToken()), tokenModel, SaOAuth2Manager.getConfig().getAccessTokenTimeout());
|
||||
|
||||
// 将此 CodeModel 当做 refresh_token 保存下来
|
||||
SaTokenManager.getSaTokenDao().setObject(getKeyRefreshToken(tokenModel.getRefreshToken()), codeModel, SaOAuth2Manager.getConfig().getRefreshTokenTimeout());
|
||||
SaManager.getSaTokenDao().setObject(getKeyRefreshToken(tokenModel.getRefreshToken()), codeModel, SaOAuth2Manager.getConfig().getRefreshTokenTimeout());
|
||||
|
||||
// 返回
|
||||
return tokenModel;
|
||||
@ -352,7 +352,7 @@ public interface SaOAuth2Interface {
|
||||
* @return AccessTokenModel (授权码Model)
|
||||
*/
|
||||
public default AccessTokenModel getAccessToken(String accessToken) {
|
||||
return (AccessTokenModel)SaTokenManager.getSaTokenDao().getObject(getKeyAccessToken(accessToken));
|
||||
return (AccessTokenModel)SaManager.getSaTokenDao().getObject(getKeyAccessToken(accessToken));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -369,7 +369,7 @@ public interface SaOAuth2Interface {
|
||||
// 获取新的 AccessToken 并保存
|
||||
AccessTokenModel tokenModel = converCodeToAccessToken(codeModel);
|
||||
tokenModel.setRefreshToken(refreshToken);
|
||||
SaTokenManager.getSaTokenDao().setObject(getKeyAccessToken(tokenModel.getAccessToken()), tokenModel, SaOAuth2Manager.getConfig().getAccessTokenTimeout());
|
||||
SaManager.getSaTokenDao().setObject(getKeyAccessToken(tokenModel.getAccessToken()), tokenModel, SaOAuth2Manager.getConfig().getAccessTokenTimeout());
|
||||
|
||||
// 返回
|
||||
return tokenModel;
|
||||
@ -381,7 +381,7 @@ public interface SaOAuth2Interface {
|
||||
* @return RefreshToken (授权码Model)
|
||||
*/
|
||||
public default CodeModel getRefreshToken(String refreshToken) {
|
||||
return (CodeModel)SaTokenManager.getSaTokenDao().getObject(getKeyRefreshToken(refreshToken));
|
||||
return (CodeModel)SaManager.getSaTokenDao().getObject(getKeyRefreshToken(refreshToken));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -390,7 +390,7 @@ public interface SaOAuth2Interface {
|
||||
* @return 有效期
|
||||
*/
|
||||
public default long getAccessTokenExpiresIn(String accessToken) {
|
||||
return SaTokenManager.getSaTokenDao().getObjectTimeout(getKeyAccessToken(accessToken));
|
||||
return SaManager.getSaTokenDao().getObjectTimeout(getKeyAccessToken(accessToken));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -399,7 +399,7 @@ public interface SaOAuth2Interface {
|
||||
* @return 有效期
|
||||
*/
|
||||
public default long getRefreshTokenExpiresIn(String refreshToken) {
|
||||
return SaTokenManager.getSaTokenDao().getObjectTimeout(getKeyRefreshToken(refreshToken));
|
||||
return SaManager.getSaTokenDao().getObjectTimeout(getKeyRefreshToken(refreshToken));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -519,7 +519,7 @@ public interface SaOAuth2Interface {
|
||||
* @return key
|
||||
*/
|
||||
public default String getKeyCodeModel(String code) {
|
||||
return SaTokenManager.getConfig().getTokenName() + ":oauth2:code:" + code;
|
||||
return SaManager.getConfig().getTokenName() + ":oauth2:code:" + code;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -529,7 +529,7 @@ public interface SaOAuth2Interface {
|
||||
* @return key
|
||||
*/
|
||||
public default String getKeyClientLoginId(Object loginId, String clientId) {
|
||||
return SaTokenManager.getConfig().getTokenName() + ":oauth2:newest-code:" + clientId + ":" + loginId;
|
||||
return SaManager.getConfig().getTokenName() + ":oauth2:newest-code:" + clientId + ":" + loginId;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -538,7 +538,7 @@ public interface SaOAuth2Interface {
|
||||
* @return key
|
||||
*/
|
||||
public default String getKeyRefreshToken(String refreshToken) {
|
||||
return SaTokenManager.getConfig().getTokenName() + ":oauth2:refresh-token:" + refreshToken;
|
||||
return SaManager.getConfig().getTokenName() + ":oauth2:refresh-token:" + refreshToken;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -547,7 +547,7 @@ public interface SaOAuth2Interface {
|
||||
* @return key
|
||||
*/
|
||||
public default String getKeyAccessToken(String accessToken) {
|
||||
return SaTokenManager.getConfig().getTokenName() + ":oauth2:access-token:" + accessToken;
|
||||
return SaManager.getConfig().getTokenName() + ":oauth2:access-token:" + accessToken;
|
||||
}
|
||||
|
||||
|
||||
|
@ -95,7 +95,7 @@ public class SaReactorFilter implements WebFilter {
|
||||
}
|
||||
|
||||
|
||||
// ------------------------ 执行函数
|
||||
// ------------------------ 钩子函数
|
||||
|
||||
/**
|
||||
* 认证函数:每次请求执行
|
||||
@ -109,6 +109,11 @@ public class SaReactorFilter implements WebFilter {
|
||||
throw new SaTokenException(e);
|
||||
};
|
||||
|
||||
/**
|
||||
* 前置函数:在每次[认证函数]之前执行
|
||||
*/
|
||||
public SaFilterAuthStrategy beforeAuth = r -> {};
|
||||
|
||||
/**
|
||||
* 写入[认证函数]: 每次请求执行
|
||||
* @param auth see note
|
||||
@ -129,6 +134,16 @@ public class SaReactorFilter implements WebFilter {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入[前置函数]:在每次[认证函数]之前执行
|
||||
* @param auth see note
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaReactorFilter setBeforeAuth(SaFilterAuthStrategy beforeAuth) {
|
||||
this.beforeAuth = beforeAuth;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------ filter
|
||||
|
||||
@ -140,7 +155,10 @@ public class SaReactorFilter implements WebFilter {
|
||||
SaReactorSyncHolder.setContent(exchange);
|
||||
|
||||
// 执行全局过滤器
|
||||
SaRouterUtil.match(includeList, excludeList, () -> auth.run(null));
|
||||
SaRouterUtil.match(includeList, excludeList, () -> {
|
||||
beforeAuth.run(null);
|
||||
auth.run(null);
|
||||
});
|
||||
|
||||
} catch (Throwable e) {
|
||||
// 1. 获取异常处理策略结果
|
||||
|
@ -63,11 +63,18 @@ public class SaRequestForReactor implements SaRequest {
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回当前请求的URL
|
||||
* 返回当前请求path (不包括上下文名称)
|
||||
*/
|
||||
@Override
|
||||
public String getRequestURI() {
|
||||
public String getRequestPath() {
|
||||
return request.getURI().getPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回当前请求的类型
|
||||
*/
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return request.getMethodValue();
|
||||
}
|
||||
}
|
||||
|
@ -71,4 +71,13 @@ public class SaResponseForReactor implements SaResponse {
|
||||
response.addCookie(builder.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 在响应头里写入一个值
|
||||
*/
|
||||
@Override
|
||||
public SaResponse setHeader(String name, String value) {
|
||||
response.getHeaders().set(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.PathMatcher;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.action.SaTokenAction;
|
||||
import cn.dev33.satoken.config.SaTokenConfig;
|
||||
import cn.dev33.satoken.context.SaTokenContext;
|
||||
@ -42,7 +42,7 @@ public class SaTokenSpringAutowired {
|
||||
*/
|
||||
@Autowired
|
||||
public void setConfig(SaTokenConfig saTokenConfig) {
|
||||
SaTokenManager.setConfig(saTokenConfig);
|
||||
SaManager.setConfig(saTokenConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,7 +52,7 @@ public class SaTokenSpringAutowired {
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
public void setSaTokenDao(SaTokenDao saTokenDao) {
|
||||
SaTokenManager.setSaTokenDao(saTokenDao);
|
||||
SaManager.setSaTokenDao(saTokenDao);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,7 +62,7 @@ public class SaTokenSpringAutowired {
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
public void setStpInterface(StpInterface stpInterface) {
|
||||
SaTokenManager.setStpInterface(stpInterface);
|
||||
SaManager.setStpInterface(stpInterface);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -72,7 +72,7 @@ public class SaTokenSpringAutowired {
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
public void setSaTokenAction(SaTokenAction saTokenAction) {
|
||||
SaTokenManager.setSaTokenAction(saTokenAction);
|
||||
SaManager.setSaTokenAction(saTokenAction);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,7 +100,7 @@ public class SaTokenSpringAutowired {
|
||||
*/
|
||||
@Autowired
|
||||
public void setSaTokenContext(SaTokenContext saTokenContext) {
|
||||
SaTokenManager.setSaTokenContext(saTokenContext);
|
||||
SaManager.setSaTokenContext(saTokenContext);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -110,7 +110,7 @@ public class SaTokenSpringAutowired {
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
public void setSaTokenListener(SaTokenListener saTokenListener) {
|
||||
SaTokenManager.setSaTokenListener(saTokenListener);
|
||||
SaManager.setSaTokenListener(saTokenListener);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,11 +66,19 @@ public class SaRequestForServlet implements SaRequest {
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回当前请求的URL
|
||||
* 返回当前请求path (不包括上下文名称)
|
||||
*/
|
||||
@Override
|
||||
public String getRequestURI() {
|
||||
return request.getRequestURI();
|
||||
public String getRequestPath() {
|
||||
return request.getServletPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回当前请求的类型
|
||||
*/
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return request.getMethod();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -59,4 +59,14 @@ public class SaResponseForServlet implements SaResponse {
|
||||
response.addCookie(cookie);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 在响应头里写入一个值
|
||||
*/
|
||||
@Override
|
||||
public SaResponse setHeader(String name, String value) {
|
||||
response.setHeader(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ public class SaServletFilter implements Filter {
|
||||
}
|
||||
|
||||
|
||||
// ------------------------ 执行函数
|
||||
// ------------------------ 钩子函数
|
||||
|
||||
/**
|
||||
* 认证函数:每次请求执行
|
||||
@ -109,6 +109,11 @@ public class SaServletFilter implements Filter {
|
||||
throw new SaTokenException(e);
|
||||
};
|
||||
|
||||
/**
|
||||
* 前置函数:在每次[认证函数]之前执行
|
||||
*/
|
||||
public SaFilterAuthStrategy beforeAuth = r -> {};
|
||||
|
||||
/**
|
||||
* 写入[认证函数]: 每次请求执行
|
||||
* @param auth see note
|
||||
@ -129,6 +134,16 @@ public class SaServletFilter implements Filter {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入[前置函数]:在每次[认证函数]之前执行
|
||||
* @param auth see note
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaServletFilter setBeforeAuth(SaFilterAuthStrategy beforeAuth) {
|
||||
this.beforeAuth = beforeAuth;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------ doFilter
|
||||
|
||||
@ -138,7 +153,10 @@ public class SaServletFilter implements Filter {
|
||||
|
||||
try {
|
||||
// 执行全局过滤器
|
||||
SaRouterUtil.match(includeList, excludeList, () -> auth.run(null));
|
||||
SaRouterUtil.match(includeList, excludeList, () -> {
|
||||
beforeAuth.run(null);
|
||||
auth.run(null);
|
||||
});
|
||||
|
||||
} catch (Throwable e) {
|
||||
// 1. 获取异常处理策略结果
|
||||
|
@ -6,7 +6,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.PathMatcher;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.action.SaTokenAction;
|
||||
import cn.dev33.satoken.config.SaTokenConfig;
|
||||
import cn.dev33.satoken.context.SaTokenContext;
|
||||
@ -41,7 +41,7 @@ public class SaTokenSpringAutowired {
|
||||
*/
|
||||
@Autowired
|
||||
public void setConfig(SaTokenConfig saTokenConfig) {
|
||||
SaTokenManager.setConfig(saTokenConfig);
|
||||
SaManager.setConfig(saTokenConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -51,7 +51,7 @@ public class SaTokenSpringAutowired {
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
public void setSaTokenDao(SaTokenDao saTokenDao) {
|
||||
SaTokenManager.setSaTokenDao(saTokenDao);
|
||||
SaManager.setSaTokenDao(saTokenDao);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,7 +61,7 @@ public class SaTokenSpringAutowired {
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
public void setStpInterface(StpInterface stpInterface) {
|
||||
SaTokenManager.setStpInterface(stpInterface);
|
||||
SaManager.setStpInterface(stpInterface);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,7 +71,7 @@ public class SaTokenSpringAutowired {
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
public void setSaTokenAction(SaTokenAction saTokenAction) {
|
||||
SaTokenManager.setSaTokenAction(saTokenAction);
|
||||
SaManager.setSaTokenAction(saTokenAction);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -91,7 +91,7 @@ public class SaTokenSpringAutowired {
|
||||
*/
|
||||
@Autowired
|
||||
public void setSaTokenContext(SaTokenContext saTokenContext) {
|
||||
SaTokenManager.setSaTokenContext(saTokenContext);
|
||||
SaManager.setSaTokenContext(saTokenContext);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,7 +101,7 @@ public class SaTokenSpringAutowired {
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
public void setSaTokenListener(SaTokenListener saTokenListener) {
|
||||
SaTokenManager.setSaTokenListener(saTokenListener);
|
||||
SaManager.setSaTokenListener(saTokenListener);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user