mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-10-22 03:27:23 +08:00
feat(core): 封禁模块新增支持实时从数据库查询数据
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2020-2099 sa-token.cc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.model.wrapperInfo;
|
||||
|
||||
/**
|
||||
* 返回值包装类:描述一个账号是否已被封禁等信息
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.40.0
|
||||
*/
|
||||
public class SaDisableWrapperInfo {
|
||||
|
||||
/**
|
||||
* 是否被封禁
|
||||
*/
|
||||
public boolean isDisable;
|
||||
|
||||
/**
|
||||
* 封禁剩余时间,单位:秒(-1=永久封禁,0 or -2=未封禁)
|
||||
*/
|
||||
public long disableTime;
|
||||
|
||||
/**
|
||||
* 封禁等级(最小1级,0=未封禁)
|
||||
*/
|
||||
public int disableLevel;
|
||||
|
||||
/**
|
||||
* 构建对象
|
||||
*
|
||||
* @param isDisable 是否被封禁
|
||||
* @param disableTime 封禁剩余时间,单位:秒(-1=永久封禁,0 or -2=未封禁)
|
||||
* @param disableLevel 封禁等级(最小1级,0=未封禁)
|
||||
*/
|
||||
public SaDisableWrapperInfo(boolean isDisable, long disableTime, int disableLevel) {
|
||||
this.isDisable = isDisable;
|
||||
this.disableTime = disableTime;
|
||||
this.disableLevel = disableLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个已封禁描述对象
|
||||
* @param disableTime 封禁时间
|
||||
* @param disableLevel 封禁等级
|
||||
* @return /
|
||||
*/
|
||||
public static SaDisableWrapperInfo createDisabled(long disableTime, int disableLevel) {
|
||||
return new SaDisableWrapperInfo(true, disableTime, disableLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个未封禁描述对象
|
||||
* @return /
|
||||
*/
|
||||
public static SaDisableWrapperInfo createNotDisabled() {
|
||||
return new SaDisableWrapperInfo(false, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个未封禁描述对象,并指定缓存时间,指定时间内不再重复查询
|
||||
* @param cacheTime 缓存时间(单位:秒)
|
||||
* @return /
|
||||
*/
|
||||
public static SaDisableWrapperInfo createNotDisabled(long cacheTime) {
|
||||
return new SaDisableWrapperInfo(false, cacheTime, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SaDisableWrapperInfo{" +
|
||||
"isDisable=" + isDisable +
|
||||
", disableTime=" + disableTime +
|
||||
", disableLevel=" + disableLevel +
|
||||
'}';
|
||||
}
|
||||
|
||||
// setter / getter 仅为兼容部分框架序列化操作,不建议调用
|
||||
|
||||
public boolean getIsDisable() {
|
||||
return isDisable;
|
||||
}
|
||||
|
||||
public SaDisableWrapperInfo setIsDisable(boolean isDisable) {
|
||||
this.isDisable = isDisable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getDisableTime() {
|
||||
return disableTime;
|
||||
}
|
||||
|
||||
public SaDisableWrapperInfo setDisableTime(long disableTime) {
|
||||
this.disableTime = disableTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getDisableLevel() {
|
||||
return disableLevel;
|
||||
}
|
||||
|
||||
public SaDisableWrapperInfo setDisableLevel(int disableLevel) {
|
||||
this.disableLevel = disableLevel;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@@ -15,10 +15,12 @@
|
||||
*/
|
||||
package cn.dev33.satoken.stp;
|
||||
|
||||
import cn.dev33.satoken.model.wrapperInfo.SaDisableWrapperInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 权限数据加载源接口
|
||||
* 权限数据源加载接口
|
||||
*
|
||||
* <p>
|
||||
* 在使用权限校验 API 之前,你必须实现此接口,告诉框架哪些用户拥有哪些权限。<br>
|
||||
@@ -48,4 +50,15 @@ public interface StpInterface {
|
||||
*/
|
||||
List<String> getRoleList(Object loginId, String loginType);
|
||||
|
||||
/**
|
||||
* 返回指定账号 id 是否被封禁
|
||||
*
|
||||
* @param loginId 账号id
|
||||
* @param service 业务标识符
|
||||
* @return 描述该账号是否封禁的包装信息对象
|
||||
*/
|
||||
default SaDisableWrapperInfo isDisabled(Object loginId, String service) {
|
||||
return SaDisableWrapperInfo.createNotDisabled();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -29,6 +29,7 @@ import cn.dev33.satoken.error.SaErrorCode;
|
||||
import cn.dev33.satoken.exception.*;
|
||||
import cn.dev33.satoken.fun.SaFunction;
|
||||
import cn.dev33.satoken.listener.SaTokenEventCenter;
|
||||
import cn.dev33.satoken.model.wrapperInfo.SaDisableWrapperInfo;
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
import cn.dev33.satoken.session.TokenSign;
|
||||
import cn.dev33.satoken.strategy.SaStrategy;
|
||||
@@ -2413,8 +2414,8 @@ public class StpLogic {
|
||||
if(SaFoxUtil.isEmpty(service)) {
|
||||
throw new SaTokenException("请提供要封禁的服务").setCode(SaErrorCode.CODE_11063);
|
||||
}
|
||||
if(level < SaTokenConsts.MIN_DISABLE_LEVEL) {
|
||||
throw new SaTokenException("封禁等级不可以小于最小值:" + SaTokenConsts.MIN_DISABLE_LEVEL).setCode(SaErrorCode.CODE_11064);
|
||||
if(level < SaTokenConsts.MIN_DISABLE_LEVEL && level != 0) {
|
||||
throw new SaTokenException("封禁等级不可以小于最小值:" + SaTokenConsts.MIN_DISABLE_LEVEL + " (0除外)").setCode(SaErrorCode.CODE_11064);
|
||||
}
|
||||
|
||||
// 打上封禁标记
|
||||
@@ -2473,13 +2474,12 @@ public class StpLogic {
|
||||
*/
|
||||
public void checkDisableLevel(Object loginId, String service, int level) {
|
||||
// 1、先前置检查一下这个账号是否被封禁了
|
||||
String value = getSaTokenDao().get(splicingKeyDisable(loginId, service));
|
||||
if(SaFoxUtil.isEmpty(value)) {
|
||||
int disableLevel = getDisableLevel(loginId, service);
|
||||
if(disableLevel == SaTokenConsts.NOT_DISABLE_LEVEL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 2、再判断被封禁的等级是否达到了指定级别
|
||||
Integer disableLevel = SaFoxUtil.getValueByType(value, int.class);
|
||||
if(disableLevel >= level) {
|
||||
throw new DisableServiceException(loginType, loginId, service, disableLevel, level, getDisableTime(loginId, service))
|
||||
.setCode(SaErrorCode.CODE_11061);
|
||||
@@ -2504,14 +2504,22 @@ public class StpLogic {
|
||||
* @return /
|
||||
*/
|
||||
public int getDisableLevel(Object loginId, String service) {
|
||||
// 1、判断是否被封禁了,如果尚未被封禁,返回-2
|
||||
// 1、先从缓存中查询数据,缓存中有值,以缓存值优先
|
||||
String value = getSaTokenDao().get(splicingKeyDisable(loginId, service));
|
||||
if(SaFoxUtil.isEmpty(value)) {
|
||||
return SaTokenConsts.NOT_DISABLE_LEVEL;
|
||||
if(SaFoxUtil.isNotEmpty(value)) {
|
||||
return SaFoxUtil.getValueByType(value, int.class);
|
||||
}
|
||||
|
||||
// 2、转为 int 类型返回
|
||||
return SaFoxUtil.getValueByType(value, int.class);
|
||||
// 2、如果缓存中无数据,则从"数据加载器"中再次查询
|
||||
SaDisableWrapperInfo disableWrapperInfo = SaManager.getStpInterface().isDisabled(loginId, service);
|
||||
|
||||
// 如果返回值 disableTime 有效,则代表返回结果需要写入缓存
|
||||
if(disableWrapperInfo.disableTime == SaTokenDao.NEVER_EXPIRE || disableWrapperInfo.disableTime > 0) {
|
||||
disableLevel(loginId, service, disableWrapperInfo.disableLevel, disableWrapperInfo.disableTime);
|
||||
}
|
||||
|
||||
// 返回查询结果
|
||||
return disableWrapperInfo.disableLevel;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user