我们先看一下官网介绍,sa-token有什么功能

链接: 官网地址
主要是Shiro、Security配置繁琐,这个简单易上手
这是他的大致功能点,今天我们搞点基础的

springBoot 集成sa-token 并实现登录的验证和权限的鉴定

首先导入maven坐标
导入redis主要是sa-token使用内存来存取token的,使用redis第三方来做到重启项目token不丢,只需导入sa-token-redis的maven即可,不需要手动get,set

   <!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ --><dependency><groupId>cn.dev33</groupId><artifactId>sa-token-spring-boot-starter</artifactId><version>1.25.0</version></dependency><!-- sa-token整合redis (使用jdk默认序列化方式) --><dependency><groupId>cn.dev33</groupId><artifactId>sa-token-dao-redis</artifactId><version>1.25.0</version></dependency>

yml配置文件配一下

server:port: 8010spring:servlet:multipart:enabled: truelocation: C:/var/guoheng/picture/max-file-size: 10MBmax-request-size: 10MBdatasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/fire_control?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&allowMultiQueries=true&serverTimezone=GMT%2B8username: rootpassword: roottype: com.alibaba.druid.pool.DruidDataSource#########  druid连接池配置  #########druid:# 连接池建立时创建的初始化连接数initial-size: 1# 连接池中最大的活跃连接数max-active: 20# 连接池中最小的活跃连接数min-idle: 1# 连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。max-wait: 60000# 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。pool-prepared-statements: false# 指定每个连接上PSCache的大小,要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100。max-pool-prepared-statement-per-connection-size: -1# 用来检测连接是否有效的sql,要求是一个查询语句。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用。(不同数据库不同)validation-query: SELECT 'x'# 指定连接校验查询的超时时间,单位:秒。validation-query-timeout: 1# 是否在获得连接后检测其可用性,连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。test-on-borrow: false# 是否在连接放回连接池后检测其可用性,做了这个配置会降低性能。test-on-return: false# 是否在连接空闲一段时间后检测其可用性,建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。test-while-idle: true# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒。time-between-eviction-runs-millis: 60000# 配置一个连接在池中最小生存的时间,单位是毫秒。min-evictable-idle-time-millis: 300000# 登陆超时时间,单位是秒。login-timeout: 3# 查询超时时间,单位是秒。query-timeout: 3# 事务查询超时时间,单位是秒。transaction-query-timeout: 60# 异步关闭连接。async-close-connection-enable: true# 属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有:监控统计用的filter:stat,日志用的filter:log4j,防御sql注入的filter:wallfilters: stat##########  StatViewServlet监控配置  ##########stat-view-servlet:login-username: guohenglogin-password: guohengallow:deny:aop:auto: true###################  redis配置  ###################redis:host: 127.0.0.1port: 6379password:jedis:pool:max-active: 8max-wait: -1max-idle: 8min-idle: 0time-between-eviction-runs: 30000################### sa-token配置 ###################
sa-token:# token名称 (同时也是cookie名称)token-name: satoken# token有效期,单位s 默认30, -1代表永不过期timeout: 2592000# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒activity-timeout: 3600# 是否允许同一账号并发登录 (true时允许一起登录,false时新登录挤掉旧登录)is-concurrent: true# 在多人登录同一账号时,是否共用一个token (true时所有登录共用一个token,false时每次登录新建一个token)is-share: false# token风格token-style: simple-uuid# 是否输出操作日志is-log: falsemybatis:mapper-locations: classpath*:mapper/*.xml

接下来是很重要的两个sa-token的config(使用过滤器的路由鉴权)
PS:拦截器鉴权N多坑,不传satoken也能访问接口

特别注意路由一定要有区分性,例如:/user和/user/{id} 这种方式satoken框架认为是同一个路由!!导致路由鉴权将两个权限码合并认证

package com.demo.app.config.satoken;import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.filter.SaServletFilter;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import result.Result;import java.util.Arrays;/*** @program: fire* @description:* @author: fbl* @create: 2021-08-31 12:15**/
@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {/*** 注册 [sa-token全局过滤器]*/@Beanpublic SaServletFilter getSaServletFilter() {return new SaServletFilter()// 指定 [拦截路由] 与 [放行路由].addInclude("/**").addExclude()// 认证函数: 每次请求执行.setAuth(r -> {System.out.println("---------- sa全局认证");SaRouter.match(Arrays.asList("/**"), Arrays.asList("/login","/druid/**","/default/**","/","/swagger-ui.html","/swagger-resources/**","swagger/**","/webjars/**","/swagger-ui.html/*","/swagger-resources","/*.html","/**/*.html","/**/*.css","/**/*.js","/**/*.svg","/**/*.ico","/**/*.png","/**/*.jpg","/**/*.xlsx","/**/*.docx","/**/*.pdf","/webSocket/**","/*/api-docs","/v2/api-docs-ext"), StpUtil::checkLogin);// 路由一定要有区分性SaRouter.match("/user", () -> StpUtil.checkPermission("0001"));SaRouter.match("/user/get/{id}", () -> StpUtil.checkPermission("001101"));})// 异常处理函数:每次认证函数发生异常时执行此函数.setError(e -> {return Result.failure(e.getMessage());})// 前置函数:在每次认证函数之前执行.setBeforeAuth(r -> {// ---------- 设置一些安全响应头 ----------SaHolder.getResponse()// 服务器名称.setServer("sa-server")// 是否可以在iframe显示视图: DENY=不可以 | SAMEORIGIN=同域下可以 | ALLOW-FROM uri=指定域名下可以.setHeader("X-Frame-Options", "SAMEORIGIN")// 是否启用浏览器默认XSS防护: 0=禁用 | 1=启用 | 1; mode=block 启用, 并在检查到XSS攻击时,停止渲染页面.setHeader("X-Frame-Options", "1; mode=block")// 禁用浏览器内容嗅探.setHeader("X-Content-Type-Options", "nosniff");});}}

这里是设置登录用户权限和角色的地方(从权限\角色表中查询放置),这里我只校验了权限,没有校验角色

package com.demo.app.config.satoken;import cn.dev33.satoken.stp.StpInterface;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.demo.app.mapper.permission.PermissionMapper;
import com.demo.app.mapper.permission.RolePermissionMapper;
import com.demo.app.mapper.role.RoleMapper;
import com.demo.app.mapper.user.UserMapper;
import com.demo.app.mapper.user.UserRoleMapper;
import model.entity.sys.RolePermission;
import model.entity.sys.SysPermission;
import model.entity.sys.SysRole;
import model.entity.sys.UserRole;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.List;
import java.util.stream.Collectors;/*** @program: fire* @description: 用户登录赋予相应权限* @author: fbl* @create: 2021-08-31 13:07**/
@Component
public class StpInterfaceImpl implements StpInterface {@AutowiredUserMapper userMapper;@AutowiredUserRoleMapper userRoleMapper;@AutowiredRoleMapper roleMapper;@AutowiredPermissionMapper permissionMapper;@AutowiredRolePermissionMapper rolePermissionMapper;@Overridepublic List<String> getPermissionList(Object userId, String s) {// 用户存在,查找角色QueryWrapper<UserRole> userRoleQueryWrapper = new QueryWrapper<>();userRoleQueryWrapper.eq("user_id", userId);List<UserRole> userRoles = userRoleMapper.selectList(userRoleQueryWrapper);// 角色查找权限QueryWrapper<RolePermission> rolePermissionQueryWrapper = new QueryWrapper<>();rolePermissionQueryWrapper.in("role_id", userRoles.stream().map(UserRole::getRoleId).collect(Collectors.toList()));List<RolePermission> rolePermissions = rolePermissionMapper.selectList(rolePermissionQueryWrapper);QueryWrapper<SysPermission> permissionQueryWrapper = new QueryWrapper<>();permissionQueryWrapper.in("id", rolePermissions.stream().map(RolePermission::getPermissionId).distinct().collect(Collectors.toList()));List<SysPermission> sysPermissions = permissionMapper.selectList(permissionQueryWrapper);List<String> permissions = sysPermissions.stream().map(SysPermission::getCode).distinct().collect(Collectors.toList());return permissions;}@Overridepublic List<String> getRoleList(Object userId, String s) {// 用户存在,查找角色QueryWrapper<UserRole> userRoleQueryWrapper = new QueryWrapper<>();userRoleQueryWrapper.eq("user_id", userId);List<UserRole> userRoles = userRoleMapper.selectList(userRoleQueryWrapper);// 查询角色QueryWrapper<SysRole> sysRoleQueryWrapper = new QueryWrapper<SysRole>().in("id", userRoles.stream().map(UserRole::getRoleId).collect(Collectors.toList()));List<SysRole> sysRoles = roleMapper.selectList(sysRoleQueryWrapper);List<String> roleNames = sysRoles.stream().map(SysRole::getRoleName).distinct().collect(Collectors.toList());return roleNames;}
}

打这里认证鉴权就完成了,快把,赶紧来测试一下吧

还有一个配置文件冲突的问题,之前我在webMvc里面配置的有静态文件读取和跨域等,与satoken的配置起了冲突,我修改了自己的配置文件

package com.demo.app.config.webmvc;import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** 类功能描述: CorsConfig** @author Eternal* @date 2019-11-26 15:11*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Value("${spring.servlet.multipart.location}")private String uploadFileUrl;/*** 跨域配置** @param registry*/@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("*").allowedMethods("POST", "GET", "PUT", "DELETE", "OPTIONS").maxAge(3600)// 是否允许发送Cookie.allowCredentials(true).allowedHeaders("*");}@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {// 静态文件registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");// swaggerregistry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");// 上传文件registry.addResourceHandler("/file/**").addResourceLocations("file:/" + uploadFileUrl);}
}

测试一下

拿到token放进header里取请求需要权限的接口
没有权限
拥有权限

最后一点:用户登录过后,header中不用传satoken也能进行鉴权(自动拿的是登录的用户的satoken),多个用户登录拿的是最后一个用户登录的satoken,好扯,也就是说必须要传satoken
总结:感觉没有SpringSecurity+JWT好用

发现一款java鉴权认证框架sa-token(目前好像坑还很多)相关推荐

  1. Python 技术篇-百度语音API鉴权认证获取Access Token实例演示

    百度语音官方鉴权认证文档 下面来为大家进行鉴权认证获取Access Token的演示: 首先需要创建自己的个人语音应用,在应用列表里进行创建. 百度语音个人应用列表 然后用这个应用里的 API Key ...

  2. 鉴权/认证框架Spring Security和Apache Shiro比较

    参考: https://www.cnblogs.com/minxiang-luo/p/12492905.html https://www.javadevjournal.com/spring-boot/ ...

  3. java鉴权_一个开箱即用的高效认证鉴权框架,专注于restful api的认证鉴权动态保护...

    作者:tomsun28 来源:SegmentFault 思否 写在开头 看了看这个专栏的最近一篇文章已经是两年前了,时间过得好快.应该是出学校后时间就很快了.两年前因为用shiro后,自己就按着想法开 ...

  4. aka鉴权 ims_ims 注册鉴权认证过程

    移动通信的安全问题正越来越多地受到关注.2G网络主要传输语音业务,采用的是单向的用户认证方案,即网络能够验证用户身份是否合法,而用户无法确认其所连接的网络服务是否可靠.然而,3G网络将会演变成一个覆盖 ...

  5. 大数据Hadoop之——Zookeeper鉴权认证(Kerberos认证+账号密码认证)

    文章目录 一.Zookeeper概述与安装 二.Zookeeper Kerberos 鉴权认证 1)Kerberos安装 2)创建用户并生成keytab鉴权文件(前期准备) 3)独立zookeeper ...

  6. ims 注册鉴权认证过程

    摘要:IP多媒体子系统(IMS)作为3G网络的核心控制平台,其安全问题正面临着严峻的挑战.IMS的接入认证机制的实现作为整个IMS安全方案实施的第一步,是保证IMS系统安全的关键.基于认证和密钥协商( ...

  7. Onvif协议学习:7、鉴权认证

    Onvif协议学习:7.鉴权认证 文章目录 Onvif协议学习:7.鉴权认证 1.前言 2.ONVIF哪些接口需要认证 3.如何认证 4.安装OpenSSL 5.实现认证 6.特别注意 原文链接:ht ...

  8. .Net Core使用Ocelot网关(二) -鉴权认证

    前言 上一章.Net Core使用Ocelot网关(一) -负载,限流,熔断,Header转换 已经简单的介绍了ocelot的使用了,但是网关暴露的接口如果什么人都能访问的话安全性就太低啦.所以我们需 ...

  9. 核心网upf作用_高性能5G核心网,动力从何而来? 核心网,是整个通信网络的大脑,是不可或缺的重要组成部分。 网络的管理控制、鉴权认证等关键功能,主要由核心网负责。核心网的... - 雪球...

    来源:雪球App,作者: 鲜枣课堂,(https://xueqiu.com/7282046183/152278945) 核心网,是整个通信网络的大脑,是不可或缺的重要组成部分. 网络的管理控制.鉴权认 ...

最新文章

  1. 2021湖北省普通高考成绩查询果,2021年湖北高考录取结果查询登录网址入口
  2. 深度学习经典案例解析:YOLO系列
  3. 从某次测试过程中,得到的MySQL性能优化的建议,和定位问题的方法
  4. 用JavaScript实现动态省市县三级联动
  5. 本周值得读:13 份最新开源「Paper + Code」
  6. 国家集训队 小Z的袜子
  7. python 将列表值赋予函数_python把空列表作为函数默认参数,可是有坑的
  8. 【Redis】Redis Hyperloglog
  9. 程序员出差是去干什么_为什么女生不适合做程序员?原来互联网公司女生少,是由于这几点...
  10. Qt 发布 Android 自动驾驶技术预览
  11. 灵灵兔人事考勤薪资软件系统kqwins:连接失败
  12. 计算机网络二进制计算题
  13. android苹果模拟器哪个好,mac安卓模拟器哪个好用?为你推荐网易mumu模拟器
  14. 计算机屏幕截图按什么键,电脑按什么键自由截图
  15. 学习cairo的心得及资料
  16. Python编程 条件判断语句
  17. 怎么查自己电脑服务器信息吗,如何查看自己电脑的服务器
  18. R语言丨根据VCF文件自动填充对其变异位点并生成序列fa文件
  19. ubuntu16.04无法联网
  20. 记2019.7日照夏令营

热门文章

  1. 干货丨如何使用DolphinDB计算K线
  2. BCM以太网驱动初始化简要
  3. 【打印PPT】如何打印PPT?如何打印PPT到1张纸上?PPT大于A4纸张如何打印?
  4. 评测三款最流行的azw3阅读器
  5. django部署机器学习模型---搭建新闻推荐系统
  6. 【word 2019 for Mac实用教程】word文档如何去除页眉横线?
  7. 二叉树 - 递归计算二叉树的高度(C语言)
  8. 组件化设计思维 – 从规范到工具的构建与探索
  9. JavaScript|免费导入题库,考试复习工具,刷题神器,支持导入excel题库【完全免费+提供源码】
  10. 《码农翻身》读后感---程序员的潜规则