更改配置前缀

This commit is contained in:
click33 2021-07-01 15:15:54 +08:00
parent d2e00b341d
commit 7b69b7915b
38 changed files with 1348 additions and 309 deletions

View File

@ -32,7 +32,7 @@ public class SaManager {
/**
* 配置文件 Bean
*/
private static SaTokenConfig config;
public static SaTokenConfig config;
public static void setConfig(SaTokenConfig config) {
SaManager.config = config;
if(config.getIsPrint()) {

View File

@ -304,5 +304,4 @@ public class SaFoxUtil {
}
}
}

View File

@ -2,38 +2,38 @@
server:
port: 8081
spring:
# Sa-Token配置
sa-token:
# Token名称 (同时也是cookie名称)
token-name: satoken
# Token有效期单位s 默认30天, -1代表永不过期
timeout: 2592000
# Token风格
token-style: uuid
# 配置Sa-Token单独使用的Redis连接
alone-redis:
# Redis数据库索引默认为0
database: 2
# Redis服务器地址
host: 127.0.0.1
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码默认为空
password:
# 连接超时时间(毫秒)
timeout: 10ms
lettuce:
pool:
# 连接池最大连接数
max-active: 200
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# 连接池中的最大空闲连接
max-idle: 10
# 连接池中的最小空闲连接
min-idle: 0
# Sa-Token配置
sa-token:
# Token名称 (同时也是cookie名称)
token-name: satoken
# Token有效期单位s 默认30天, -1代表永不过期
timeout: 2592000
# Token风格
token-style: uuid
# 配置Sa-Token单独使用的Redis连接
alone-redis:
# Redis数据库索引默认为0
database: 2
# Redis服务器地址
host: 127.0.0.1
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码默认为空
password:
# 连接超时时间(毫秒)
timeout: 10ms
lettuce:
pool:
# 连接池最大连接数
max-active: 200
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# 连接池中的最大空闲连接
max-idle: 10
# 连接池中的最小空闲连接
min-idle: 0
spring:
# 配置业务使用的Redis连接
redis:
# Redis数据库索引默认为0

View File

@ -82,7 +82,7 @@
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
<!-- <version>2.3.1</version> -->
</dependency>
</dependencies>

View File

@ -2,21 +2,21 @@
server:
port: 8081
# sa-token配置
sa-token:
# token名称 (同时也是cookie名称)
token-name: satoken
# token有效期单位s 默认30天, -1代表永不过期
timeout: 2592000
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
activity-timeout: -1
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: true
# 在多人登录同一账号时是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: true
# token风格
token-style: uuid
spring:
# sa-token配置
sa-token:
# token名称 (同时也是cookie名称)
token-name: satoken
# token有效期单位s 默认30天, -1代表永不过期
timeout: 2592000
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
activity-timeout: -1
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
allow-concurrent-login: true
# 在多人登录同一账号时是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: true
# token风格
token-style: uuid
# redis配置
redis:
# Redis数据库索引默认为0

View File

@ -68,5 +68,5 @@ public class SaTokenConfigure implements WebMvcConfigurer {
})
;
}
}

View File

@ -0,0 +1,52 @@
package com.pj.satoken.at;
import java.lang.reflect.AnnotatedElement;
import org.springframework.core.annotation.AnnotatedElementUtils;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.action.SaTokenActionDefaultImpl;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaCheckSafe;
/**
* 继承Sa-Token行为Bean默认实现, 重写部分逻辑
*/
//@Component
public class MySaTokenAction extends SaTokenActionDefaultImpl {
/**
* 重写Sa-Token的注解处理器加强注解合并功能
* @param target see note
*/
@Override
protected void validateAnnotation(AnnotatedElement target) {
// 校验 @SaCheckLogin 注解
if(AnnotatedElementUtils.isAnnotated(target, SaCheckLogin.class)) {
SaCheckLogin at = AnnotatedElementUtils.getMergedAnnotation(target, SaCheckLogin.class);
SaManager.getStpLogic(at.type()).checkByAnnotation(at);
}
// 校验 @SaCheckRole 注解
if(AnnotatedElementUtils.isAnnotated(target, SaCheckRole.class)) {
SaCheckRole at = AnnotatedElementUtils.getMergedAnnotation(target, SaCheckRole.class);
SaManager.getStpLogic(at.type()).checkByAnnotation(at);
}
// 校验 @SaCheckPermission 注解
if(AnnotatedElementUtils.isAnnotated(target, SaCheckPermission.class)) {
SaCheckPermission at = AnnotatedElementUtils.getMergedAnnotation(target, SaCheckPermission.class);
SaManager.getStpLogic(at.type()).checkByAnnotation(at);
}
// 校验 @SaCheckSafe 注解
if(AnnotatedElementUtils.isAnnotated(target, SaCheckSafe.class)) {
SaCheckSafe at = AnnotatedElementUtils.getMergedAnnotation(target, SaCheckSafe.class);
SaManager.getStpLogic(null).checkByAnnotation(at);
}
}
}

View File

@ -0,0 +1,21 @@
package com.pj.satoken.at;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import cn.dev33.satoken.annotation.SaCheckLogin;
/**
* 登录认证(User版)只有登录之后才能进入该方法
* <p> 可标注在函数类上效果等同于标注在此类的所有方法上
* @author kong
*
*/
@SaCheckLogin(type = StpUserUtil.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE})
public @interface SaUserCheckLogin {
}

View File

@ -0,0 +1,38 @@
package com.pj.satoken.at;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
/**
* 权限认证(User版)必须具有指定权限才能进入该方法
* <p> 可标注在函数类上效果等同于标注在此类的所有方法上
* @author kong
*
*/
@SaCheckPermission(type = StpUserUtil.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE})
public @interface SaUserCheckPermission {
/**
* 需要校验的权限码
* @return 需要校验的权限码
*/
@AliasFor(annotation = SaCheckPermission.class)
String [] value() default {};
/**
* 验证模式AND | OR默认AND
* @return 验证模式
*/
@AliasFor(annotation = SaCheckPermission.class)
SaMode mode() default SaMode.AND;
}

View File

@ -0,0 +1,38 @@
package com.pj.satoken.at;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaMode;
/**
* 角色认证(User版)必须具有指定角色标识才能进入该方法
* <p> 可标注在函数类上效果等同于标注在此类的所有方法上
* @author kong
*
*/
@SaCheckRole(type = StpUserUtil.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE})
public @interface SaUserCheckRole {
/**
* 需要校验的角色标识
* @return 需要校验的角色标识
*/
@AliasFor(annotation = SaCheckRole.class)
String [] value() default {};
/**
* 验证模式AND | OR默认AND
* @return 验证模式
*/
@AliasFor(annotation = SaCheckRole.class)
SaMode mode() default SaMode.AND;
}

View File

@ -0,0 +1,697 @@
package com.pj.satoken.at;
import java.util.List;
import org.springframework.stereotype.Component;
import cn.dev33.satoken.fun.SaFunction;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpLogic;
/**
* Sa-Token 权限验证工具类 (User版)
* @author kong
*/
@Component
public class StpUserUtil {
/**
* 账号类型标识
*/
public static final String TYPE = "user";
/**
* 底层的 StpLogic 对象
*/
public static StpLogic stpLogic = new StpLogic(TYPE);
/**
* 获取当前 StpLogic 的账号类型
* @return See Note
*/
public static String getLoginType(){
return stpLogic.getLoginType();
}
// =================== 获取token 相关 ===================
/**
* 返回token名称
* @return 此StpLogic的token名称
*/
public static String getTokenName() {
return stpLogic.getTokenName();
}
/**
* 在当前会话写入当前TokenValue
* @param tokenValue token值
* @param cookieTimeout Cookie存活时间()
*/
public static void setTokenValue(String tokenValue, int cookieTimeout){
stpLogic.setTokenValue(tokenValue, cookieTimeout);
}
/**
* 获取当前TokenValue
* @return 当前tokenValue
*/
public static String getTokenValue() {
return stpLogic.getTokenValue();
}
/**
* 获取当前会话的Token信息
* @return token信息
*/
public static SaTokenInfo getTokenInfo() {
return stpLogic.getTokenInfo();
}
// =================== 登录相关操作 ===================
/**
* 会话登录
* @param id 账号id建议的类型long | int | String
*/
public static void login(Object id) {
stpLogic.login(id);
}
/**
* 会话登录并指定登录设备
* @param id 账号id建议的类型long | int | String
* @param device 设备标识
*/
public static void login(Object id, String device) {
stpLogic.login(id, device);
}
/**
* 会话登录并指定是否 [记住我]
* @param id 账号id建议的类型long | int | String
* @param isLastingCookie 是否为持久Cookie
*/
public static void login(Object id, boolean isLastingCookie) {
stpLogic.login(id, isLastingCookie);
}
/**
* 会话登录并指定所有登录参数Model
* @param id 登录id建议的类型long | int | String
* @param loginModel 此次登录的参数Model
*/
public static void login(Object id, SaLoginModel loginModel) {
stpLogic.login(id, loginModel);
}
/**
* 会话注销
*/
public static void logout() {
stpLogic.logout();
}
/**
* 会话注销根据指定Token
* @param tokenValue 指定token
*/
public static void logoutByTokenValue(String tokenValue) {
stpLogic.logoutByTokenValue(tokenValue);
}
/**
* 会话注销根据账号id 踢人下线
* <p> 当对方再次访问系统时会抛出NotLoginException异常场景值=-2
* @param loginId 账号id
*/
public static void logoutByLoginId(Object loginId) {
stpLogic.logoutByLoginId(loginId);
}
/**
* 会话注销根据账号id & 设备标识 踢人下线
* <p> 当对方再次访问系统时会抛出NotLoginException异常场景值=-2
* @param loginId 账号id
* @param device 设备标识
*/
public static void logoutByLoginId(Object loginId, String device) {
stpLogic.logoutByLoginId(loginId, device);
}
// 查询相关
/**
* 当前会话是否已经登录
* @return 是否已登录
*/
public static boolean isLogin() {
return stpLogic.isLogin();
}
/**
* 检验当前会话是否已经登录如未登录则抛出异常
*/
public static void checkLogin() {
stpLogic.checkLogin();
}
/**
* 获取当前会话账号id, 如果未登录则抛出异常
* @return 账号id
*/
public static Object getLoginId() {
return stpLogic.getLoginId();
}
/**
* 获取当前会话账号id, 如果未登录则返回默认值
* @param <T> 返回类型
* @param defaultValue 默认值
* @return 登录id
*/
public static <T> T getLoginId(T defaultValue) {
return stpLogic.getLoginId(defaultValue);
}
/**
* 获取当前会话账号id, 如果未登录则返回null
* @return 账号id
*/
public static Object getLoginIdDefaultNull() {
return stpLogic.getLoginIdDefaultNull();
}
/**
* 获取当前会话账号id, 并转换为String类型
* @return 账号id
*/
public static String getLoginIdAsString() {
return stpLogic.getLoginIdAsString();
}
/**
* 获取当前会话账号id, 并转换为int类型
* @return 账号id
*/
public static int getLoginIdAsInt() {
return stpLogic.getLoginIdAsInt();
}
/**
* 获取当前会话账号id, 并转换为long类型
* @return 账号id
*/
public static long getLoginIdAsLong() {
return stpLogic.getLoginIdAsLong();
}
/**
* 获取指定Token对应的账号id如果未登录则返回 null
* @param tokenValue token
* @return 账号id
*/
public static Object getLoginIdByToken(String tokenValue) {
return stpLogic.getLoginIdByToken(tokenValue);
}
// =================== session相关 ===================
/**
* 获取指定账号id的Session, 如果Session尚未创建isCreate=是否新建并返回
* @param loginId 账号id
* @param isCreate 是否新建
* @return Session对象
*/
public static SaSession getSessionByLoginId(Object loginId, boolean isCreate) {
return stpLogic.getSessionByLoginId(loginId, isCreate);
}
/**
* 获取指定key的Session, 如果Session尚未创建则返回null
* @param sessionId SessionId
* @return Session对象
*/
public static SaSession getSessionBySessionId(String sessionId) {
return stpLogic.getSessionBySessionId(sessionId);
}
/**
* 获取指定账号id的Session如果Session尚未创建则新建并返回
* @param loginId 账号id
* @return Session对象
*/
public static SaSession getSessionByLoginId(Object loginId) {
return stpLogic.getSessionByLoginId(loginId);
}
/**
* 获取当前会话的Session, 如果Session尚未创建isCreate=是否新建并返回
* @param isCreate 是否新建
* @return Session对象
*/
public static SaSession getSession(boolean isCreate) {
return stpLogic.getSession(isCreate);
}
/**
* 获取当前会话的Session如果Session尚未创建则新建并返回
* @return Session对象
*/
public static SaSession getSession() {
return stpLogic.getSession();
}
// =================== token专属session ===================
/**
* 获取指定Token-Session如果Session尚未创建则新建并返回
* @param tokenValue Token值
* @return Session对象
*/
public static SaSession getTokenSessionByToken(String tokenValue) {
return stpLogic.getTokenSessionByToken(tokenValue);
}
/**
* 获取当前Token-Session如果Session尚未创建则新建并返回
* @return Session对象
*/
public static SaSession getTokenSession() {
return stpLogic.getTokenSession();
}
// =================== [临时过期] 验证相关 ===================
/**
* 检查当前token 是否已经[临时过期]如果已经过期则抛出异常
*/
public static void checkActivityTimeout() {
stpLogic.checkActivityTimeout();
}
/**
* 续签当前token( [最后操作时间] 更新为当前时间戳)
* <h1>请注意: 即时token已经 [临时过期] 也可续签成功
* 如果此场景下需要提示续签失败可在此之前调用 checkActivityTimeout() 强制检查是否过期即可 </h1>
*/
public static void updateLastActivityToNow() {
stpLogic.updateLastActivityToNow();
}
// =================== 过期时间相关 ===================
/**
* 获取当前登录者的token剩余有效时间 (单位: )
* @return token剩余有效时间
*/
public static long getTokenTimeout() {
return stpLogic.getTokenTimeout();
}
/**
* 获取当前登录者的Session剩余有效时间 (单位: )
* @return token剩余有效时间
*/
public static long getSessionTimeout() {
return stpLogic.getSessionTimeout();
}
/**
* 获取当前token的专属Session剩余有效时间 (单位: )
* @return token剩余有效时间
*/
public static long getTokenSessionTimeout() {
return stpLogic.getTokenSessionTimeout();
}
/**
* 获取当前token[临时过期]剩余有效时间 (单位: )
* @return token[临时过期]剩余有效时间
*/
public static long getTokenActivityTimeout() {
return stpLogic.getTokenActivityTimeout();
}
// =================== 角色验证操作 ===================
/**
* 指定账号id是否含有角色标识, 返回true或false
* @param loginId 账号id
* @param role 角色标识
* @return 是否含有指定角色标识
*/
public static boolean hasRole(Object loginId, String role) {
return stpLogic.hasRole(loginId, role);
}
/**
* 当前账号是否含有指定角色标识, 返回true或false
* @param role 角色标识
* @return 是否含有指定角色标识
*/
public static boolean hasRole(String role) {
return stpLogic.hasRole(role);
}
/**
* 当前账号是否含有指定角色标识, 如果验证未通过则抛出异常: NotRoleException
* @param role 角色标识
*/
public static void checkRole(String role) {
stpLogic.checkRole(role);
}
/**
* 当前账号是否含有指定角色标识 [指定多个必须全部验证通过]
* @param roleArray 角色标识数组
*/
public static void checkRoleAnd(String... roleArray){
stpLogic.checkRoleAnd(roleArray);
}
/**
* 当前账号是否含有指定角色标识 [指定多个只要其一验证通过即可]
* @param roleArray 角色标识数组
*/
public static void checkRoleOr(String... roleArray){
stpLogic.checkRoleOr(roleArray);
}
// =================== 权限验证操作 ===================
/**
* 指定账号id是否含有指定权限, 返回true或false
* @param loginId 账号id
* @param permission 权限码
* @return 是否含有指定权限
*/
public static boolean hasPermission(Object loginId, String permission) {
return stpLogic.hasPermission(loginId, permission);
}
/**
* 当前账号是否含有指定权限, 返回true或false
* @param permission 权限码
* @return 是否含有指定权限
*/
public static boolean hasPermission(String permission) {
return stpLogic.hasPermission(permission);
}
/**
* 当前账号是否含有指定权限, 如果验证未通过则抛出异常: NotPermissionException
* @param permission 权限码
*/
public static void checkPermission(String permission) {
stpLogic.checkPermission(permission);
}
/**
* 当前账号是否含有指定权限 [指定多个必须全部验证通过]
* @param permissionArray 权限码数组
*/
public static void checkPermissionAnd(String... permissionArray) {
stpLogic.checkPermissionAnd(permissionArray);
}
/**
* 当前账号是否含有指定权限 [指定多个只要其一验证通过即可]
* @param permissionArray 权限码数组
*/
public static void checkPermissionOr(String... permissionArray) {
stpLogic.checkPermissionOr(permissionArray);
}
// =================== id 反查token 相关操作 ===================
/**
* 获取指定账号id的tokenValue
* <p> 在配置为允许并发登录时此方法只会返回队列的最后一个token
* 如果你需要返回此账号id的所有token请调用 getTokenValueListByLoginId
* @param loginId 账号id
* @return token值
*/
public static String getTokenValueByLoginId(Object loginId) {
return stpLogic.getTokenValueByLoginId(loginId);
}
/**
* 获取指定账号id指定设备端的tokenValue
* <p> 在配置为允许并发登录时此方法只会返回队列的最后一个token
* 如果你需要返回此账号id的所有token请调用 getTokenValueListByLoginId
* @param loginId 账号id
* @param device 设备标识
* @return token值
*/
public static String getTokenValueByLoginId(Object loginId, String device) {
return stpLogic.getTokenValueByLoginId(loginId, device);
}
/**
* 获取指定账号id的tokenValue集合
* @param loginId 账号id
* @return 此loginId的所有相关token
*/
public static List<String> getTokenValueListByLoginId(Object loginId) {
return stpLogic.getTokenValueListByLoginId(loginId);
}
/**
* 获取指定账号id指定设备端的tokenValue 集合
* @param loginId 账号id
* @param device 设备标识
* @return 此loginId的所有相关token
*/
public static List<String> getTokenValueListByLoginId(Object loginId, String device) {
return stpLogic.getTokenValueListByLoginId(loginId, device);
}
/**
* 返回当前会话的登录设备
* @return 当前令牌的登录设备
*/
public static String getLoginDevice() {
return stpLogic.getLoginDevice();
}
// =================== 会话管理 ===================
/**
* 根据条件查询Token
* @param keyword 关键字
* @param start 开始处索引 (-1代表查询所有)
* @param size 获取数量
* @return token集合
*/
public static List<String> searchTokenValue(String keyword, int start, int size) {
return stpLogic.searchTokenValue(keyword, start, size);
}
/**
* 根据条件查询SessionId
* @param keyword 关键字
* @param start 开始处索引 (-1代表查询所有)
* @param size 获取数量
* @return sessionId集合
*/
public static List<String> searchSessionId(String keyword, int start, int size) {
return stpLogic.searchSessionId(keyword, start, size);
}
/**
* 根据条件查询Token专属Session的Id
* @param keyword 关键字
* @param start 开始处索引 (-1代表查询所有)
* @param size 获取数量
* @return sessionId集合
*/
public static List<String> searchTokenSessionId(String keyword, int start, int size) {
return stpLogic.searchTokenSessionId(keyword, start, size);
}
// ------------------- 账号封禁 -------------------
/**
* 封禁指定账号
* <p> 此方法不会直接将此账号id踢下线而是在对方再次登录时抛出`DisableLoginException`异常
* @param loginId 指定账号id
* @param disableTime 封禁时间, 单位: -1=永久封禁
*/
public static void disable(Object loginId, long disableTime) {
stpLogic.disable(loginId, disableTime);
}
/**
* 指定账号是否已被封禁 (true=已被封禁, false=未被封禁)
* @param loginId 账号id
* @return see note
*/
public static boolean isDisable(Object loginId) {
return stpLogic.isDisable(loginId);
}
/**
* 获取指定账号剩余封禁时间单位-1=永久封禁-2=未被封禁
* @param loginId 账号id
* @return see note
*/
public static long getDisableTime(Object loginId) {
return stpLogic.getDisableTime(loginId);
}
/**
* 解封指定账号
* @param loginId 账号id
*/
public static void untieDisable(Object loginId) {
stpLogic.untieDisable(loginId);
}
// =================== 身份切换 ===================
/**
* 临时切换身份为指定账号id
* @param loginId 指定loginId
*/
public static void switchTo(Object loginId) {
stpLogic.switchTo(loginId);
}
/**
* 结束临时切换身份
*/
public static void endSwitch() {
stpLogic.endSwitch();
}
/**
* 当前是否正处于[身份临时切换]
* @return 是否正处于[身份临时切换]
*/
public static boolean isSwitch() {
return stpLogic.isSwitch();
}
/**
* 在一个代码段里方法内临时切换身份为指定账号id
* @param loginId 指定账号id
* @param function 要执行的方法
*/
public static void switchTo(Object loginId, SaFunction function) {
stpLogic.switchTo(loginId, function);
}
// ------------------- 二级认证 -------------------
/**
* 在当前会话 开启二级认证
* @param timeout 维持时间 (单位: )
*/
public static void openSafe(long safeTime) {
stpLogic.openSafe(safeTime);
}
/**
* 当前会话 是否处于二级认证时间内
* @return true=二级认证已通过, false=尚未进行二级认证或认证已超时
*/
public static boolean isSafe() {
return stpLogic.isSafe();
}
/**
* 检查当前会话是否已通过二级认证如未通过则抛出异常
*/
public static void checkSafe() {
stpLogic.checkSafe();
}
/**
* 获取当前会话的二级认证剩余有效时间 (单位: , 返回-2代表尚未通过二级认证)
* @return
*/
public static long getSafeTime() {
return stpLogic.getSafeTime();
}
/**
* 在当前会话 结束二级认证
*/
public static void closeSafe() {
stpLogic.closeSafe();
}
// =================== 历史API兼容旧版本 ===================
/**
* <h1> 本函数设计已过时未来版本可能移除此函数请及时更换为 StpUtil.getLoginType() 使用方式保持不变 </h1>
* 获取当前StpLogin的loginKey
* @return 当前StpLogin的loginKey
*/
@Deprecated
public static String getLoginKey(){
return stpLogic.getLoginType();
}
/**
* <h1> 本函数设计已过时未来版本可能移除此函数请及时更换为 StpUtil.login() 使用方式保持不变 </h1>
* 在当前会话上登录id
* @param loginId 登录id建议的类型long | int | String
*/
@Deprecated
public static void setLoginId(Object loginId) {
stpLogic.login(loginId);
}
/**
* <h1> 本函数设计已过时未来版本可能移除此函数请及时更换为 StpUtil.login() 使用方式保持不变 </h1>
* 在当前会话上登录id, 并指定登录设备
* @param loginId 登录id建议的类型long | int | String
* @param device 设备标识
*/
@Deprecated
public static void setLoginId(Object loginId, String device) {
stpLogic.login(loginId, device);
}
/**
* <h1> 本函数设计已过时未来版本可能移除此函数请及时更换为 StpUtil.login() 使用方式保持不变 </h1>
* 在当前会话上登录id, 并指定登录设备
* @param loginId 登录id建议的类型long | int | String
* @param isLastingCookie 是否为持久Cookie
*/
@Deprecated
public static void setLoginId(Object loginId, boolean isLastingCookie) {
stpLogic.login(loginId, isLastingCookie);
}
/**
* <h1> 本函数设计已过时未来版本可能移除此函数请及时更换为 StpUtil.login() 使用方式保持不变 </h1>
* 在当前会话上登录id, 并指定所有登录参数Model
* @param loginId 登录id建议的类型long | int | String
* @param loginModel 此次登录的参数Model
*/
@Deprecated
public static void setLoginId(Object loginId, SaLoginModel loginModel) {
stpLogic.login(loginId, loginModel);
}
}

View File

@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pj.satoken.at.StpUserUtil;
import com.pj.util.AjaxJson;
import com.pj.util.Ttime;
@ -241,7 +242,8 @@ public class TestController {
@RequestMapping("test")
public AjaxJson test() {
System.out.println("进来了");
return AjaxJson.getSuccess("访问成功");
StpUserUtil.login(10001);
return AjaxJson.getSuccess();
}
// 测试 浏览器访问 http://localhost:8081/test/test2

View File

@ -1,25 +1,25 @@
# 端口
server:
port: 8081
spring:
# sa-token配置
sa-token:
# token名称 (同时也是cookie名称)
token-name: satoken
# token有效期单位s 默认30天, -1代表永不过期
timeout: 2592000
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
activity-timeout: -1
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: false
# 在多人登录同一账号时是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: true
# token风格
token-style: uuid
# 是否输出操作日志
is-log: false
# sa-token配置
sa-token:
# token名称 (同时也是cookie名称)
token-name: satoken
# token有效期单位s 默认30天, -1代表永不过期
timeout: 2592000
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
activity-timeout: -1
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: false
# 在多人登录同一账号时是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: true
# token风格
token-style: uuid
# 是否输出操作日志
is-log: false
spring:
# redis配置
redis:
# Redis数据库索引默认为0

View File

@ -2,8 +2,7 @@
server:
port: 8081
spring:
sa-token:
# 写入Cookie时显式指定的作用域, 用于单点登录二级域名共享Cookie
cookie-domain: stp.com
sa-token:
# 写入Cookie时显式指定的作用域, 用于单点登录二级域名共享Cookie
cookie-domain: stp.com

View File

@ -2,42 +2,41 @@
server:
port: 9001
spring:
# sa-token配置
sa-token:
# Token名称
token-name: satoken
# Token有效期
timeout: 2592000
# Token风格
token-style: uuid
# SSO-相关配置
sso:
# SSO-Server端 单点登录地址
auth-url: http://sa-sso-server.com:9000/ssoAuth
# 配置Sa-Token单独使用的Redis连接 此处需要和SSO-Server端连接同一个Redis
alone-redis:
# Redis数据库索引
database: 1
# Redis服务器地址
host: 127.0.0.1
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码默认为空
password:
# 连接超时时间(毫秒)
timeout: 10ms
lettuce:
pool:
# 连接池最大连接数
max-active: 200
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# 连接池中的最大空闲连接
max-idle: 10
# 连接池中的最小空闲连接
min-idle: 0
# sa-token配置
sa-token:
# Token名称
token-name: satoken
# Token有效期
timeout: 2592000
# Token风格
token-style: uuid
# SSO-相关配置
sso:
# SSO-Server端 单点登录地址
auth-url: http://sa-sso-server.com:9000/ssoAuth
# 配置Sa-Token单独使用的Redis连接 此处需要和SSO-Server端连接同一个Redis
alone-redis:
# Redis数据库索引
database: 1
# Redis服务器地址
host: 127.0.0.1
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码默认为空
password:
# 连接超时时间(毫秒)
timeout: 10ms
lettuce:
pool:
# 连接池最大连接数
max-active: 200
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# 连接池中的最大空闲连接
max-idle: 10
# 连接池中的最小空闲连接
min-idle: 0

View File

@ -2,16 +2,16 @@
server:
port: 9000
spring:
# Sa-Token配置
sa-token:
# SSO-相关配置
sso:
# Ticket有效期 (单位: 秒),默认五分钟
ticket-timeout: 300
# 所有允许的授权回调地址 (此处为了方便测试配置为*,线上生产环境一定要配置为详细地地址)
allow-url: http://sa-sso-client1.com:9001/ssoLogin, http://sa-sso-client2.com:9001/ssoLogin, http://sa-sso-client3.com:9001/ssoLogin
# Sa-Token配置
sa-token:
# SSO-相关配置
sso:
# Ticket有效期 (单位: 秒),默认五分钟
ticket-timeout: 300
# 所有允许的授权回调地址 (此处为了方便测试配置为*,线上生产环境一定要配置为详细地地址)
allow-url: http://sa-sso-client1.com:9001/ssoLogin, http://sa-sso-client2.com:9001/ssoLogin, http://sa-sso-client3.com:9001/ssoLogin
spring:
# Redis配置
redis:
# Redis数据库索引默认为0

View File

@ -2,26 +2,26 @@
server:
port: 9001
spring:
# sa-token配置
sa-token:
# Token名称
token-name: satoken
# Token有效期
timeout: 2592000
# Token风格
token-style: uuid
# SSO-相关配置
sso:
# SSO-Server端 单点登录地址
auth-url: http://sa-sso-server.com:9000/ssoAuth
# SSO-Server端 ticket校验地址
check-ticket-url: http://sa-sso-server.com:9000/checkTicket
# SSO-Server端 单点注销地址
slo-url: http://sa-sso-server.com:9000/ssoLogout
# 接口调用秘钥用于SSO模式三的单点注销功能
secretkey: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
# sa-token配置
sa-token:
# Token名称
token-name: satoken
# Token有效期
timeout: 2592000
# Token风格
token-style: uuid
# SSO-相关配置
sso:
# SSO-Server端 单点登录地址
auth-url: http://sa-sso-server.com:9000/ssoAuth
# SSO-Server端 ticket校验地址
check-ticket-url: http://sa-sso-server.com:9000/checkTicket
# SSO-Server端 单点注销地址
slo-url: http://sa-sso-server.com:9000/ssoLogout
# 接口调用秘钥用于SSO模式三的单点注销功能
secretkey: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
spring:
# 配置Sa-Token单独使用的Redis连接 此处需要和SSO-Server端连接同一个Redis
redis:
# Redis数据库索引

View File

@ -2,18 +2,18 @@
server:
port: 9000
spring:
# Sa-Token配置
sa-token:
# SSO-相关配置
sso:
# Ticket有效期 (单位: 秒),默认五分钟
ticket-timeout: 300
# 所有允许的授权回调地址
allow-url: http://sa-sso-client1.com:9001/ssoLogin, http://sa-sso-client2.com:9001/ssoLogin, http://sa-sso-client3.com:9001/ssoLogin
# 接口调用秘钥用于SSO模式三的单点注销功能
secretkey: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
# Sa-Token配置
sa-token:
# SSO-相关配置
sso:
# Ticket有效期 (单位: 秒),默认五分钟
ticket-timeout: 300
# 所有允许的授权回调地址
allow-url: http://sa-sso-client1.com:9001/ssoLogin, http://sa-sso-client2.com:9001/ssoLogin, http://sa-sso-client3.com:9001/ssoLogin
# 接口调用秘钥用于SSO模式三的单点注销功能
secretkey: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
spring:
# Redis配置
redis:
# Redis数据库索引默认为0

View File

@ -2,23 +2,22 @@
server:
port: 8081
# sa-token配置
sa-token:
# token名称 (同时也是cookie名称)
token-name: satoken
# token有效期单位s 默认30天, -1代表永不过期
timeout: 2592000
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
activity-timeout: -1
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: true
# 在多人登录同一账号时是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: true
# token风格
token-style: uuid
spring:
# sa-token配置
sa-token:
# token名称 (同时也是cookie名称)
token-name: satoken
# token有效期单位s 默认30天, -1代表永不过期
timeout: 2592000
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
activity-timeout: -1
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: true
# 在多人登录同一账号时是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: true
# token风格
token-style: uuid
# redis配置
redis:
# Redis数据库索引默认为0

View File

@ -24,39 +24,37 @@ Sa-Token默认的Redis集成方式会把权限数据和业务缓存放在一起
### 2、然后在application.yml中增加配置
``` yml
# 端口
spring:
# Sa-Token配置
sa-token:
# Token名称
token-name: satoken
# Token有效期
timeout: 2592000
# Token风格
token-style: uuid
# 配置Sa-Token单独使用的Redis连接
alone-redis:
# Redis数据库索引默认为0
database: 2
# Redis服务器地址
host: 127.0.0.1
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码默认为空
password:
# 连接超时时间(毫秒)
timeout: 10ms
lettuce:
pool:
# 连接池最大连接数
max-active: 200
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# 连接池中的最大空闲连接
max-idle: 10
# 连接池中的最小空闲连接
min-idle: 0
# Sa-Token配置
sa-token:
# Token名称
token-name: satoken
# Token有效期
timeout: 2592000
# Token风格
token-style: uuid
# 配置Sa-Token单独使用的Redis连接
alone-redis:
# Redis数据库索引默认为0
database: 2
# Redis服务器地址
host: 127.0.0.1
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码默认为空
password:
# 连接超时时间(毫秒)
timeout: 10ms
lettuce:
pool:
# 连接池最大连接数
max-active: 200
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# 连接池中的最大空闲连接
max-idle: 10
# 连接池中的最小空闲连接
min-idle: 0
```
具体可参考:[码云application.yml](https://gitee.com/dromara/sa-token/blob/dev/sa-token-demo/sa-token-demo-alone-redis/src/main/resources/application.yml)

View File

@ -66,8 +66,7 @@ SaTempUtil.getTimeout(token);
并在配置文件中配置上jwt秘钥 **`(必填!)`**
``` java
spring:
sa-token:
# sa-token-temp-jwt 模块的秘钥 (随便乱摁几个字母就行了)
jwt-secret-key: JfdDSgfCmPsDfmsAaQwnXk
sa-token:
# sa-token-temp-jwt 模块的秘钥 (随便乱摁几个字母就行了)
jwt-secret-key: JfdDSgfCmPsDfmsAaQwnXk
```

View File

@ -50,10 +50,9 @@ Sa-Token整合同域下的单点登录非常简单相比于正常的登录
#### 2. 指定Cookie的作用域
常规情况下,在`s1.stp.com`域名访问服务器其Cookie也只能写入到`s1.stp.com`下为了将Cookie写入到其父级域名`stp.com`下,我们需要在配置文件中新增配置:
``` yml
spring:
sa-token:
# 写入Cookie时显式指定的作用域, 用于单点登录二级域名共享Cookie
cookie-domain: stp.com
sa-token:
# 写入Cookie时显式指定的作用域, 用于单点登录二级域名共享Cookie
cookie-domain: stp.com
```
#### 3. 新增测试Controller

View File

@ -1,11 +1,10 @@
<!-- 这是目录树文件 -->
<!-- 这是目录树文件 -->
- **单点登录**
- [单点登录简述](/sso/readme)
- [SSO模式一 共享Cookie同步会话](/sso/sso-type1)
- [SSO模式二 URL重定向传播会话](/sso/sso-type2)
- [SSO模式三 SSO认证中心开放接口](/sso/sso-type3)
- [SSO模式三 Http请求获取会话](/sso/sso-type3)

View File

@ -39,10 +39,9 @@ OK所有理论就绪下面开始实战
### 2、指定Cookie的作用域
在`s1.stp.com`访问服务器其Cookie也只能写入到`s1.stp.com`下为了将Cookie写入到其父级域名`stp.com`下,我们需要新增配置:
``` yml
spring:
sa-token:
# 写入Cookie时显式指定的作用域, 用于单点登录二级域名共享Cookie
cookie-domain: stp.com
sa-token:
# 写入Cookie时显式指定的作用域, 用于单点登录二级域名共享Cookie
cookie-domain: stp.com
```
### 3、新增测试Controller

View File

@ -111,16 +111,16 @@ public class SsoServerController {
server:
port: 9000
spring:
# Sa-Token配置
sa-token:
# SSO-相关配置
sso:
# Ticket有效期 (单位: 秒),默认五分钟
ticket-timeout: 300
# 所有允许的授权回调地址 (此处为了方便测试配置为*,线上生产环境一定要配置为详细地地址)
allow-url: "*"
# Sa-Token配置
sa-token:
# SSO-相关配置
sso:
# Ticket有效期 (单位: 秒),默认五分钟
ticket-timeout: 300
# 所有允许的授权回调地址 (此处为了方便测试配置为*,线上生产环境一定要配置为详细地地址)
allow-url: "*"
spring:
# Redis配置
redis:
# Redis数据库索引默认为0
@ -248,26 +248,25 @@ public class SsoClientController {
server:
port: 9001
spring:
# sa-token配置
sa-token:
# SSO-相关配置
sso:
# SSO-Server端 单点登录地址
auth-url: http://sa-sso-server.com:9000/ssoAuth
# 配置Sa-Token单独使用的Redis连接 此处需要和SSO-Server端连接同一个Redis
alone-redis:
# Redis数据库索引 (默认为0)
database: 1
# Redis服务器地址
host: 127.0.0.1
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码默认为空
password:
# sa-token配置
sa-token:
# SSO-相关配置
sso:
# SSO-Server端 单点登录地址
auth-url: http://sa-sso-server.com:9000/ssoAuth
# 配置Sa-Token单独使用的Redis连接 此处需要和SSO-Server端连接同一个Redis
alone-redis:
# Redis数据库索引 (默认为0)
database: 1
# Redis服务器地址
host: 127.0.0.1
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码默认为空
password:
```
注意点:`spring.sa-token.alone-redis` 的配置需要和SSO-Server端连接同一个Redisdatabase也要一样
注意点:`sa-token.alone-redis` 的配置需要和SSO-Server端连接同一个Redisdatabase也要一样
##### 1.4、写启动类
``` java
@ -347,7 +346,7 @@ public class SaSsoClientApplication {
### 5、配置域名校验
##### 5.1、Ticket劫持攻击
在以上的SSO-Server端示例中配置项 `spring.sa-token.sso.allow-url=*` 意为配置所有允许的Client端授权地址不在此配置项中的URL将无法单点登录成功
在以上的SSO-Server端示例中配置项 `sa-token.sso.allow-url=*` 意为配置所有允许的Client端授权地址不在此配置项中的URL将无法单点登录成功
以上示例为了方便测试被配置为*,但是,<font color="#FF0000" >在生产环境中,此配置项绝对不能配置为 * </font>否则会有被ticket劫持的风险

View File

@ -55,11 +55,10 @@ public Object checkTicket(String ticket, String sloCallback) {
##### 1.3、Client端新增配置
``` yml
spring:
sa-token:
sso:
# SSO-Server端 ticket校验地址
check-ticket-url: http://sa-sso-server.com:9000/checkTicket
sa-token:
sso:
# SSO-Server端 ticket校验地址
check-ticket-url: http://sa-sso-server.com:9000/checkTicket
```
##### 1.4、修改校验ticket的逻辑
@ -129,11 +128,10 @@ public class SsoServerLogoutController {
并在 `application.yml` 下配置API调用秘钥
``` yml
spring:
sa-token:
sso:
# API调用秘钥用于SSO模式三的单点注销功能
secretkey: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
sa-token:
sso:
# API调用秘钥用于SSO模式三的单点注销功能
secretkey: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
```
##### 2.2、SSO-Client端增加注销接口
@ -182,13 +180,12 @@ public class SsoClientLogoutController {
并在 `application.yml` 增加配置: API调用秘钥 和 单点注销接口URL
``` yml
spring:
sa-token:
sso:
# SSO-Server端 单点注销地址
slo-url: http://sa-sso-server.com:9000/ssoLogout
# 接口调用秘钥用于SSO模式三的单点注销功能
secretkey: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
sa-token:
sso:
# SSO-Server端 单点注销地址
slo-url: http://sa-sso-server.com:9000/ssoLogout
# 接口调用秘钥用于SSO模式三的单点注销功能
secretkey: kQwIOrYvnXmSDkwEiFngrKidMcdrgKor
```
##### 2.3 更改Client端首页代码

View File

@ -97,6 +97,7 @@ implementation 'cn.dev33:sa-token-core:1.20.0'
├── sa-token-spring-aop // [插件] Sa-Token 整合 SpringAOP 注解鉴权
├── sa-token-temp-jwt // [插件] Sa-Token 整合 jwt 临时令牌鉴权
├── sa-token-quick-login // [插件] Sa-Token 快速注入登录页插件
├── sa-token-alone-redis // [插件] Sa-Token 独立Redis插件实现[权限缓存与业务缓存分离]
├── sa-token-oauth2 // [插件] Sa-Token 实现 OAuth2.0 模块(内测暂未发布)
├── sa-token-demo // [示例] Sa-Token 示例合集
├── sa-token-demo-springboot // [示例] Sa-Token 整合 SpringBoot
@ -104,6 +105,12 @@ implementation 'cn.dev33:sa-token-core:1.20.0'
├── sa-token-demo-jwt // [示例] Sa-Token 集成 jwt
├── sa-token-demo-solon // [示例] Sa-Token 集成 Solon
├── sa-token-demo-quick-login // [示例] Sa-Token 集成 quick-login 模块
├── sa-token-demo-alone-redis // [示例] Sa-Token 集成 alone-redis 模块
├── sa-token-demo-sso1 // [示例] Sa-Token 集成 SSO单点登录-模式一
├── sa-token-demo-sso2-server // [示例] Sa-Token 集成 SSO单点登录-模式二 认证中心
├── sa-token-demo-sso2-client // [示例] Sa-Token 集成 SSO单点登录-模式二 应用端
├── sa-token-demo-sso3-server // [示例] Sa-Token 集成 SSO单点登录-模式三 认证中心
├── sa-token-demo-sso3-client // [示例] Sa-Token 集成 SSO单点登录-模式三 应用端
├── sa-token-demo-oauth2-server // [示例] Sa-Token 集成 OAuth2.0 (服务端)
├── sa-token-demo-oauth2-client // [示例] Sa-Token 集成 OAuth2.0 (客户端)
├── sa-token-doc // [文档] Sa-Token 开发文档

View File

@ -30,23 +30,22 @@ server:
# 端口
port: 8081
spring:
# Sa-Token配置
sa-token:
# token名称 (同时也是cookie名称)
token-name: satoken
# token有效期单位s 默认30天, -1代表永不过期
timeout: 2592000
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
activity-timeout: -1
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: false
# 在多人登录同一账号时是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: false
# token风格
token-style: uuid
# 是否输出操作日志
is-log: false
# Sa-Token配置
sa-token:
# token名称 (同时也是cookie名称)
token-name: satoken
# token有效期单位s 默认30天, -1代表永不过期
timeout: 2592000
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
activity-timeout: -1
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: false
# 在多人登录同一账号时是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: false
# token风格
token-style: uuid
# 是否输出操作日志
is-log: false
```
如果你习惯于 `application.properties` 类型的配置文件,那也很好办: <br>

View File

@ -9,27 +9,28 @@
### 方式1、在`application.yml`配置
``` java
spring:
# Sa-Token配置
sa-token:
# token名称 (同时也是cookie名称)
token-name: satoken
# token有效期单位s 默认30天, -1代表永不过期
timeout: 2592000
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
activity-timeout: -1
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: false
# 在多人登录同一账号时是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: false
# token风格
token-style: uuid
# 是否输出操作日志
is-log: false
# Sa-Token配置
sa-token:
# token名称 (同时也是cookie名称)
token-name: satoken
# token有效期单位s 默认30天, -1代表永不过期
timeout: 2592000
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
activity-timeout: -1
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: false
# 在多人登录同一账号时是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: false
# token风格
token-style: uuid
# 是否输出操作日志
is-log: false
```
如果你习惯于 `application.properties` 类型的配置文件,那也很好办: 百度: [springboot properties与yml 配置文件的区别](https://www.baidu.com/s?ie=UTF-8&wd=springboot%20properties%E4%B8%8Eyml%20%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E7%9A%84%E5%8C%BA%E5%88%AB)
!> 注:旧版本配置前缀为`[spring.sa-token.]`自v1.21.0开始,均改为`[sa-token.]`,目前版本暂时向下兼容,请尽快更新
### 方式2、通过代码配置
``` java
@ -40,9 +41,9 @@ spring:
public class SaTokenConfigure {
// 获取配置Bean (以代码的方式配置Sa-Token, 此配置会覆盖yml中的配置)
@Primary
@Bean(name="SaTokenConfigure")
public SaTokenConfig getSaTokenConfig() {
@Bean
@Primary
public SaTokenConfig getSaTokenConfigPrimary() {
SaTokenConfig config = new SaTokenConfig();
config.setTokenName("satoken"); // token名称 (同时也是cookie名称)
config.setTimeout(30 * 24 * 60 * 60); // token有效期单位s 默认30天

View File

@ -2,7 +2,7 @@
接口`SaTokenListener`是Sa-Token的全局侦听器通过实现此接口你可以在用户登陆、退出、被踢下线等关键性操作时进行一些AOP操作
框架对此侦听器的默认实现是log日志输出你可以通过配置`spring.sa-token.is-log=true`开启
框架对此侦听器的默认实现是log日志输出你可以通过配置`sa-token.is-log=true`开启
下面我们演示一下如何自定义侦听器的实现:

View File

@ -1,7 +1,7 @@
# 多账号验证
---
### 需求场景
### 0、需求场景
有的时候,我们会在一个项目中设计两套账号体系,比如一个电商系统的 `user表``admin表`<br>
在这种场景下,如果两套账号我们都使用 `StpUtil` 类的API进行登录鉴权那么势必会发生逻辑冲突
@ -9,7 +9,7 @@
要解决这个问题,我们必须有一个合理的机制将这两套账号的授权给区分开,让它们互不干扰才行
### 解决方案
### 1、解决方案
以上几篇介绍的api调用都是经过 `StpUtil` 类的各种静态方法进行授权验证,
而如果我们深入它的源码,[点此阅览](https://gitee.com/dromara/sa-token/blob/master/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java) <br/>
@ -20,7 +20,7 @@
- 在构造方法时随意传入一个不同的 `loginType`,就可以再造一套账号登录体系
### 操作示例
### 2、操作示例
比如说,对于原生`StpUtil`类,我们只做`admin账号`权限验证,而对于`user账号`,我们则:
1. 新建一个新的权限验证类,比如: `StpUserUtil.java`
@ -44,7 +44,7 @@ public class StpUserUtil {
> 成品样例参考:[码云 StpUserUtil.java](https://gitee.com/click33/sa-plus/blob/master/sp-server/src/main/java/com/pj/current/satoken/StpUserUtil.java)
### 在多账号模式下使用注解鉴权
### 3、在多账号模式下使用注解鉴权
框架默认的注解鉴权 如`@SaCheckLogin` 只针对原生`StpUtil`进行鉴权
例如,我们在一个方法上加上`@SaCheckLogin`注解,这个注解只会放行通过`StpUtil.login(id)`进行登录的会话,
@ -64,10 +64,88 @@ public String info() {
注:`@SaCheckRole("xxx")`、`@SaCheckPermission("xxx")`同理亦可根据type属性指定其校验的账号体系此属性默认为`""`,代表使用原生`StpUtil`账号体系
### 4、使用注解合并简化代码
交流群里有同学反应,虽然可以根据 `@SaCheckLogin(type = "user")` 指定账号类型,但几十上百个注解都加上这个的话,还是有些繁琐,代码也不够优雅,有么有更改的解决方案?
我们期待一种`[注解继承/合并]`的能力,即:自定义一个注解,标注上`@SaCheckLogin(type = "user")`,然后在方法上标注这个自定义注解,效果等同于标注`@SaCheckLogin(type = "user")`
很遗憾JDK默认的注解处理器并没有提供这种`[注解继承/合并]`的能力不过好在我们可以利用Spring的注解处理器达到同样的目的
1. 重写Sa-Token默认的注解处理器
``` java
/**
* 继承Sa-Token行为Bean默认实现, 重写部分逻辑
*/
@Component
public class MySaTokenAction extends SaTokenActionDefaultImpl {
/**
* 重写Sa-Token的注解处理器加强注解合并功能
*/
@Override
protected void validateAnnotation(AnnotatedElement target) {
// 校验 @SaCheckLogin 注解
if(AnnotatedElementUtils.isAnnotated(target, SaCheckLogin.class)) {
SaCheckLogin at = AnnotatedElementUtils.getMergedAnnotation(target, SaCheckLogin.class);
SaManager.getStpLogic(at.type()).checkByAnnotation(at);
}
// 校验 @SaCheckRole 注解
if(AnnotatedElementUtils.isAnnotated(target, SaCheckRole.class)) {
SaCheckRole at = AnnotatedElementUtils.getMergedAnnotation(target, SaCheckRole.class);
SaManager.getStpLogic(at.type()).checkByAnnotation(at);
}
// 校验 @SaCheckPermission 注解
if(AnnotatedElementUtils.isAnnotated(target, SaCheckPermission.class)) {
SaCheckPermission at = AnnotatedElementUtils.getMergedAnnotation(target, SaCheckPermission.class);
SaManager.getStpLogic(at.type()).checkByAnnotation(at);
}
// 校验 @SaCheckSafe 注解
if(AnnotatedElementUtils.isAnnotated(target, SaCheckSafe.class)) {
SaCheckSafe at = AnnotatedElementUtils.getMergedAnnotation(target, SaCheckSafe.class);
SaManager.getStpLogic(null).checkByAnnotation(at);
}
}
}
```
2. 自定义一个注解
``` java
/**
* 登录认证(User版):只有登录之后才能进入该方法
* <p> 可标注在函数、类上(效果等同于标注在此类的所有方法上)
*/
@SaCheckLogin(type = "user")
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE})
public @interface SaUserCheckLogin {
}
```
3. 接下来就可以使用我们的自定义注解了
``` java
// 使用 @SaUserCheckLogin 的效果等同于使用:@SaCheckLogin(type = "user")
@SaUserCheckLogin
@RequestMapping("info")
public String info() {
return "查询用户信息";
}
```
注:其它注解 `@SaCheckRole("xxx")`、`@SaCheckPermission("xxx")`同理,完整示例参考:[码云:自定义注解](https://gitee.com/dromara/sa-token/tree/dev/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/satoken/at)
### 进阶
### 5、同端多登陆
假设我们不仅需要在后台同时集成两套账号我们还需要在一个客户端同时登陆两套账号业务场景举例一个APP中可以同时登陆商家账号和用户账号
如果我们不做任何特殊处理的话,在客户端会发生`token覆盖`新登录的token会覆盖掉旧登录的token从而导致旧登录失效

View File

@ -14,11 +14,9 @@
为此我们需要在yml中添加如下配置
``` java
spring:
# Sa-Token配置
sa-token:
# token前缀
tokenPrefix: Bearer
sa-token:
# token前缀
tokenPrefix: Bearer
```
此时 Sa-Token 便可在读取token时裁剪掉 `Bearer`,成功获取`xxxx-xxxx-xxxx-xxxx`

View File

@ -10,7 +10,7 @@
Sa-Token默认的token生成策略是uuid风格, 其模样类似于:`623368f0-ae5e-4475-a53f-93e4225f16ae`<br>
如果你对这种风格不太感冒还可以将token生成设置为其他风格
怎么设置呢只需要在yml配置文件里设置 `spring.sa-token.token-style=风格类型` 即可,其有多种取值:
怎么设置呢只需要在yml配置文件里设置 `sa-token.token-style=风格类型` 即可,其有多种取值:
``` java
// 1. token-style=uuid —— uuid风格 (默认风格)

View File

@ -30,7 +30,7 @@ public class SaAloneRedisInject implements EnvironmentAware{
/**
* 配置信息的前缀
*/
public static final String ALONE_PREFIX = "spring.sa-token.alone-redis";
public static final String ALONE_PREFIX = "sa-token.alone-redis";
/**
* Sa-Token 持久层接口

View File

@ -0,0 +1,59 @@
package cn.dev33.satoken.reactor.spring;
import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import cn.dev33.satoken.util.SaTokenConsts;
/**
* 兼容旧版本的配置信息注入
* <p> 目前已处理
* <p> 1. yml配置前缀 [spring.sa-token.] 更改为 [sa-token.]
* @author kong
*/
public class SaHistoryVersionInject implements EnvironmentAware{
@Override
@SuppressWarnings("unchecked")
public void setEnvironment(Environment env) {
try {
ConfigurableEnvironment c = (ConfigurableEnvironment) env;
MutablePropertySources sources = c.getPropertySources();
// 将yml中所有 [spring.sa-token.] 开头的配置转移到 [sa-token.]
Map<String, Object> newMap = new LinkedHashMap<String, Object>();
for (PropertySource<?> source : sources) {
// 根据Name开头单词判断是否为 SpringBoot .yml 或者.properties 的配置
if(source.getName().startsWith("applicationConfig")) {
Map<String, Object> bootProp = (Map<String, Object>)source.getSource();
for (String key : bootProp.keySet()) {
if(key != null && key.startsWith("spring.sa-token.")) {
String newKey = key.substring(7);
newMap.put(newKey, bootProp.get(key));
}
}
}
}
// 追加到总配置里面
if(newMap.size() > 0) {
System.err.println("\n"
+ "Sa-Token Warning: 当前配置文件方式已过时,请更改配置前缀:原 [spring.sa-token.] 更改为 [sa-token.]\n"
+ "Sa-Token Warning: 当前版本(" + SaTokenConsts.VERSION_NO + ")暂时向下兼容,未来版本可能会完全移除旧形式");
OriginTrackedMapPropertySource source = new OriginTrackedMapPropertySource("SaHistoryVersionInjectProperty", newMap);
// 追加到末尾优先级最低
c.getPropertySources().addLast(source);
}
} catch (Exception e) {
// not handle
}
}
}

View File

@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;
import org.springframework.util.PathMatcher;
@ -24,6 +25,7 @@ import cn.dev33.satoken.temp.SaTempInterface;
*
*/
@Component
@Import(SaHistoryVersionInject.class)
public class SaTokenSpringAutowired {
/**
@ -32,7 +34,7 @@ public class SaTokenSpringAutowired {
* @return 配置对象
*/
@Bean
@ConfigurationProperties(prefix = "spring.sa-token")
@ConfigurationProperties(prefix = "sa-token")
public SaTokenConfig getSaTokenConfig() {
return new SaTokenConfig();
}

View File

@ -0,0 +1,59 @@
package cn.dev33.satoken.spring;
import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import cn.dev33.satoken.util.SaTokenConsts;
/**
* 兼容旧版本的配置信息注入
* <p> 目前已处理
* <p> 1. yml配置前缀 [spring.sa-token.] 更改为 [sa-token.]
* @author kong
*/
public class SaHistoryVersionInject implements EnvironmentAware{
@Override
@SuppressWarnings("unchecked")
public void setEnvironment(Environment env) {
try {
ConfigurableEnvironment c = (ConfigurableEnvironment) env;
MutablePropertySources sources = c.getPropertySources();
// 将yml中所有 [spring.sa-token.] 开头的配置转移到 [sa-token.]
Map<String, Object> newMap = new LinkedHashMap<String, Object>();
for (PropertySource<?> source : sources) {
// 根据Name开头单词判断是否为 SpringBoot .yml 或者.properties 的配置
if(source.getName().startsWith("applicationConfig")) {
Map<String, Object> bootProp = (Map<String, Object>)source.getSource();
for (String key : bootProp.keySet()) {
if(key != null && key.startsWith("spring.sa-token.")) {
String newKey = key.substring(7);
newMap.put(newKey, bootProp.get(key));
}
}
}
}
// 追加到总配置里面
if(newMap.size() > 0) {
System.err.println("\n"
+ "Sa-Token Warning: 当前配置文件方式已过时,请更改配置前缀:原 [spring.sa-token.] 更改为 [sa-token.]\n"
+ "Sa-Token Warning: 当前版本(" + SaTokenConsts.VERSION_NO + ")暂时向下兼容,未来版本可能会完全移除旧形式");
OriginTrackedMapPropertySource source = new OriginTrackedMapPropertySource("SaHistoryVersionInjectProperty", newMap);
// 追加到末尾优先级最低
c.getPropertySources().addLast(source);
}
} catch (Exception e) {
// not handle
}
}
}

View File

@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;
import org.springframework.util.PathMatcher;
@ -23,6 +24,7 @@ import cn.dev33.satoken.temp.SaTempInterface;
*
*/
@Component
@Import(SaHistoryVersionInject.class)
public class SaTokenSpringAutowired {
/**
@ -31,11 +33,11 @@ public class SaTokenSpringAutowired {
* @return 配置对象
*/
@Bean
@ConfigurationProperties(prefix = "spring.sa-token")
@ConfigurationProperties(prefix = "sa-token")
public SaTokenConfig getSaTokenConfig() {
return new SaTokenConfig();
}
/**
* 注入配置Bean
*