主要就是创建一个项目,引入,然后测试效果,sa-token 的网址:[在 SpringBoot 环境集成 - Sa-Token (dev33.cn)](links.jianshu.com/go?to=https… token.dev33.cn%2Fdoc%2Findex-backup.html%23%2Fstart%2Fexample "在 SpringBoot 环境集成 - Sa-Token (dev33.cn)")
第一步创建一个项目springboot,完整pom如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.auth</groupId>
<artifactId>token</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>token</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.23</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.29.0</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.17</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.jimmyshi</groupId>
<artifactId>bean-query</artifactId>
<version>1.1.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
第二步 添加yml配置文件,完整pom 如下
server:
port: 8081
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://10.0.59.65:3307/graph?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
username: root
password: 123456
type: com.alibaba.druid.pool.DruidDataSource
druid:
# 配置初始化大小、最小、最大
initial-size: 5
minIdle: 10
max-active: 20
# 配置获取连接等待超时的时间(单位:毫秒)
max-wait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 2000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 600000
max-evictable-idle-time-millis: 900000
# 用来测试连接是否可用的SQL语句,默认值每种数据库都不相同,这是mysql
validationQuery: select 1
# Sa-Token配置
sa-token:
# token名称 (同时也是cookie名称)
token-name: token
# token有效期,单位s 默认30天, -1代表永不过期
timeout: 86400
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
activity-timeout: -1
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: true
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: true
# token风格
token-style: uuid
# 是否输出操作日志
is-log: false
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
引入重要的两个配置文件
mvc 拦截器配置
/**
* @ClassName: SaTokenConfigure
*/
import cn.dev33.satoken.interceptor.SaAnnotationInterceptor;
import cn.dev33.satoken.interceptor.SaRouteInterceptor;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Component
public class SaTokenConfigure implements WebMvcConfigurer {
//放行路径
private static final String[] EXCLUDE_PATH_PATTERNS = {
"**/swagger-ui.html",
"/swagger-resources/**",
"/webjars/**",
"/v3/**",
"/swagger-ui.html/**",
"/swagger-ui/**",
"/swagger-ui/index.html#/**",
"/doc.html/**",
"/error",
"/favicon.ico",
"sso/auth",
"/csrf",
"/user/add",
"/user/reset",
"/user/edit"
};
// 注册Sa-Token的注解拦截器,打开注解式鉴权功能
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册注解拦截器,并排除不需要注解鉴权的接口地址 (与登录拦截器无关)
registry.addInterceptor(new SaRouteInterceptor((req, res, handler) -> {
// 登录认证 -- 拦截所有路由,并排除/user/login 用于开放登录
SaRouter.match("/**", "/user/login", r -> StpUtil.checkLogin());
})).addPathPatterns("/**").excludePathPatterns(EXCLUDE_PATH_PATTERNS);
// 开启aop校验权限
registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
// 续约token
registry.addInterceptor(new AuthInfoInterceptor()).addPathPatterns("/**");
}
}
个人权限集合,角色集合
@Component
@Configurationpublic class StpInterfaceConfig implements StpInterface {
@Resource
private AuthUserDao authUserDao;
@Autowired
private AuthMenuService authMenuService;
@Autowired
private AuthRoleMenuService authRoleMenuService;
@Autowired
private AuthRoleService authRoleService;
@Override
public List<String> getPermissionList(Object loginId, String loginType) {
AuthUser authUser = this.authUserDao.queryById(Integer.parseInt(loginId.toString()));
if (ObjectUtil.isNull(authUser)) {
throw new GraphExecuteException("用户不存在");
}
AuthRole authRole = authRoleService.queryById(authUser.getRoleId());
if (ObjectUtil.isNull(authRole)) {
throw new GraphExecuteException("角色不存在");
}
// 所有操作权限
List<AuthMenu> menuList = authMenuService.queryAll();
List<String> menuCodeList;
if (RoleEnum.SYSTEM.name().equals(authRole.getType())) {
menuCodeList = menuList.stream().map(AuthMenu::getMenuCode).collect(Collectors.toList());
} else {
menuCodeList = authRoleMenuService.queryByRoleId(authRole.getId());
}
return menuCodeList;
}
@Override
public List<String> getRoleList(Object loginId, String loginType) {
return new ArrayList<String>();
}
}
接下来开始一个一个尝试, 登录认证, token续约, 踢人下线, 拦截鉴权,aop权限认证
@Override
public Map doLogin(String username, String password) {
AuthUser authUser = authUserDao.queryByName(username);
if (ObjectUtil.isNull(authUser)) {
throw new GraphExecuteException("用户不存在!");
}
if (ObjectUtil.notEqual(authUser.getPassword(), SecureUtil.md5(password))) {
throw new GraphExecuteException("用户名密码不正确!");
}
StpUtil.login(authUser.getId());
SaTokenInfo saTokenInfo = StpUtil.getTokenInfo();
String token = saTokenInfo.getTokenValue();
long tokenTimeout = saTokenInfo.getTokenTimeout();
authUser.setPassword("");
HashMap<Object, Object> res = new HashMap<>();
res.put("token", token);
res.put("tokenTimeout", tokenTimeout);
res.put("info", authUser);
return res;
}
续约
/**
* @ClassName: AuthInfoInterceptor
*/
@Slf4j
public class AuthInfoInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//String tenantId = request.getHeader(TenantEnum.SYSTEM_TENANT_ID.getName());
//log.info(">>>>>>>拦截到api相关请求头<<<<<<<<" + tenantId);
//if (!StringUtils.isEmpty(tenantId)) {
// //直接搂下来,放到ThreadLocal中 后续直接从中获取
// CurrentLocal.set(TenantEnum.SYSTEM_TENANT_ID.getName(), tenantId);
//}
// 续约token
if (StpUtil.getTokenTimeout() <= StpUtil.getTokenActivityTimeout()) {
StpUtil.renewTimeout(1800);
}
return true;//注意 这里必须是true否则请求将就此终止。
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//移除app-user
//CurrentLocal.remove(TenantEnum.SYSTEM_TENANT_ID.getName());
}
}
鉴权示例, 可以在表中增加相应菜单的相应权限码,在此控制
@SaCheckPermission("usermgt") // 接口鉴权示例
@PostMapping("/page")
@ApiOperation("分页查询用户信息")
public R<PageInfo<AuthUserPageVo>> queryByPage(@RequestBody UserQueryByPageDto userQueryByPageDto) {
return R.data(this.authUserService.queryByPage(userQueryByPageDto));
}
快快自己手动尝试吧,这个框架nice的狠, 集成各种单点登录 seucrity, autho2 都ok啦
本文转自 jimolvxing.blog.csdn.net/article/det…,如有侵权,请联系删除。