mirror of
https://gitee.com/dromara/sa-token.git
synced 2024-11-30 02:48:10 +08:00
更改配置前缀
This commit is contained in:
parent
d2e00b341d
commit
7b69b7915b
@ -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()) {
|
||||
|
@ -304,5 +304,4 @@ public class SaFoxUtil {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -68,5 +68,5 @@ public class SaTokenConfigure implements WebMvcConfigurer {
|
||||
})
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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 {
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -2,8 +2,7 @@
|
||||
server:
|
||||
port: 8081
|
||||
|
||||
spring:
|
||||
sa-token:
|
||||
# 写入Cookie时显式指定的作用域, 用于单点登录二级域名共享Cookie
|
||||
cookie-domain: stp.com
|
||||
sa-token:
|
||||
# 写入Cookie时显式指定的作用域, 用于单点登录二级域名共享Cookie
|
||||
cookie-domain: stp.com
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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数据库索引
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
```
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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端连接同一个Redis(database也要一样)
|
||||
注意点:`sa-token.alone-redis` 的配置需要和SSO-Server端连接同一个Redis(database也要一样)
|
||||
|
||||
##### 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劫持的风险
|
||||
|
||||
|
@ -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端首页代码
|
||||
|
@ -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 开发文档
|
||||
|
@ -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>
|
||||
|
@ -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天
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
接口`SaTokenListener`是Sa-Token的全局侦听器,通过实现此接口,你可以在用户登陆、退出、被踢下线等关键性操作时进行一些AOP操作
|
||||
|
||||
框架对此侦听器的默认实现是log日志输出,你可以通过配置`spring.sa-token.is-log=true`开启
|
||||
框架对此侦听器的默认实现是log日志输出,你可以通过配置`sa-token.is-log=true`开启
|
||||
|
||||
下面我们演示一下如何自定义侦听器的实现:
|
||||
|
||||
|
@ -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从而导致旧登录失效
|
||||
|
@ -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`
|
||||
|
@ -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风格 (默认风格)
|
||||
|
@ -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 持久层接口
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user