发现一款java鉴权认证框架sa-token(目前好像坑还很多)
我们先看一下官网介绍,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(目前好像坑还很多)相关推荐
- Python 技术篇-百度语音API鉴权认证获取Access Token实例演示
百度语音官方鉴权认证文档 下面来为大家进行鉴权认证获取Access Token的演示: 首先需要创建自己的个人语音应用,在应用列表里进行创建. 百度语音个人应用列表 然后用这个应用里的 API Key ...
- 鉴权/认证框架Spring Security和Apache Shiro比较
参考: https://www.cnblogs.com/minxiang-luo/p/12492905.html https://www.javadevjournal.com/spring-boot/ ...
- java鉴权_一个开箱即用的高效认证鉴权框架,专注于restful api的认证鉴权动态保护...
作者:tomsun28 来源:SegmentFault 思否 写在开头 看了看这个专栏的最近一篇文章已经是两年前了,时间过得好快.应该是出学校后时间就很快了.两年前因为用shiro后,自己就按着想法开 ...
- aka鉴权 ims_ims 注册鉴权认证过程
移动通信的安全问题正越来越多地受到关注.2G网络主要传输语音业务,采用的是单向的用户认证方案,即网络能够验证用户身份是否合法,而用户无法确认其所连接的网络服务是否可靠.然而,3G网络将会演变成一个覆盖 ...
- 大数据Hadoop之——Zookeeper鉴权认证(Kerberos认证+账号密码认证)
文章目录 一.Zookeeper概述与安装 二.Zookeeper Kerberos 鉴权认证 1)Kerberos安装 2)创建用户并生成keytab鉴权文件(前期准备) 3)独立zookeeper ...
- ims 注册鉴权认证过程
摘要:IP多媒体子系统(IMS)作为3G网络的核心控制平台,其安全问题正面临着严峻的挑战.IMS的接入认证机制的实现作为整个IMS安全方案实施的第一步,是保证IMS系统安全的关键.基于认证和密钥协商( ...
- Onvif协议学习:7、鉴权认证
Onvif协议学习:7.鉴权认证 文章目录 Onvif协议学习:7.鉴权认证 1.前言 2.ONVIF哪些接口需要认证 3.如何认证 4.安装OpenSSL 5.实现认证 6.特别注意 原文链接:ht ...
- .Net Core使用Ocelot网关(二) -鉴权认证
前言 上一章.Net Core使用Ocelot网关(一) -负载,限流,熔断,Header转换 已经简单的介绍了ocelot的使用了,但是网关暴露的接口如果什么人都能访问的话安全性就太低啦.所以我们需 ...
- 核心网upf作用_高性能5G核心网,动力从何而来? 核心网,是整个通信网络的大脑,是不可或缺的重要组成部分。 网络的管理控制、鉴权认证等关键功能,主要由核心网负责。核心网的... - 雪球...
来源:雪球App,作者: 鲜枣课堂,(https://xueqiu.com/7282046183/152278945) 核心网,是整个通信网络的大脑,是不可或缺的重要组成部分. 网络的管理控制.鉴权认 ...
最新文章
- 2021湖北省普通高考成绩查询果,2021年湖北高考录取结果查询登录网址入口
- 深度学习经典案例解析:YOLO系列
- 从某次测试过程中,得到的MySQL性能优化的建议,和定位问题的方法
- 用JavaScript实现动态省市县三级联动
- 本周值得读:13 份最新开源「Paper + Code」
- 国家集训队 小Z的袜子
- python 将列表值赋予函数_python把空列表作为函数默认参数,可是有坑的
- 【Redis】Redis Hyperloglog
- 程序员出差是去干什么_为什么女生不适合做程序员?原来互联网公司女生少,是由于这几点...
- Qt 发布 Android 自动驾驶技术预览
- 灵灵兔人事考勤薪资软件系统kqwins:连接失败
- 计算机网络二进制计算题
- android苹果模拟器哪个好,mac安卓模拟器哪个好用?为你推荐网易mumu模拟器
- 计算机屏幕截图按什么键,电脑按什么键自由截图
- 学习cairo的心得及资料
- Python编程 条件判断语句
- 怎么查自己电脑服务器信息吗,如何查看自己电脑的服务器
- R语言丨根据VCF文件自动填充对其变异位点并生成序列fa文件
- ubuntu16.04无法联网
- 记2019.7日照夏令营