<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          還在用Spring Security?推薦你一款使用簡單、功能強大的權限認證框架

          共 11778字,需瀏覽 24分鐘

           ·

          2021-10-18 19:28

          今日推薦
          Java 8 一行代碼解決了空指針問題,太厲害了...
          List中remove()方法的陷阱,被坑慘了!
          25000 字詳解 23 種設計模式,原來可以這么簡單!
          最牛逼的 Java 日志框架,性能無敵,橫掃所有對手.....
          這玩意比ThreadLocal叼多了,嚇得我趕緊分享出來。


          來源:blog.csdn.net/qq_40058629/article/

          details/116692302

          我們先看一下官網介紹,sa-token有什么功能

          官網地址

          https://sa-token.dev33.cn/doc/index.html#/

          主要是Shiro、Security配置繁瑣,這個簡單易上手

          這是他的大致功能點,今天我們搞點基礎的

          springBoot 集成sa-token 并實現登錄的驗證和權限的鑒定

          首先導入maven坐標

          導入redis主要是sa-token使用內存來存取token的,使用redis第三方來做到重啟項目token不丟,只需導入sa-token-redis的maven即可,不需要手動get,set


          <dependency>
          ????<groupId>cn.dev33groupId>
          ????<artifactId>sa-token-spring-boot-starterartifactId>
          ????<version>1.25.0version>
          dependency>


          <dependency>
          ????<groupId>cn.dev33groupId>
          ????<artifactId>sa-token-dao-redisartifactId>
          ????<version>1.25.0version>
          dependency>

          yml配置文件配一下

          server:
          ??port:?8010

          spring:
          ??servlet:
          ????multipart:
          ??????enabled:?true
          ??????location:?C:/var/guoheng/picture/
          ??????max-file-size:?10MB
          ??????max-request-size:?10MB

          ??datasource:
          ????driver-class-name:?com.mysql.cj.jdbc.Driver
          ????url:?jdbc:mysql://127.0.0.1:3306/fire_control?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&allowMultiQueries=true&serverTimezone=GMT%2B8
          ????username:?root
          ????password:?root
          ????type:?com.alibaba.druid.pool.DruidDataSource
          ????#########??druid連接池配置??#########
          ????druid:
          ??????#?連接池建立時創(chuàng)建的初始化連接數
          ??????initial-size:?1
          ??????#?連接池中最大的活躍連接數
          ??????max-active:?20
          ??????#?連接池中最小的活躍連接數
          ??????min-idle:?1
          ??????#?連接時最大等待時間,單位毫秒。配置了maxWait之后,缺省啟用公平鎖,并發(fā)效率會有所下降,如果需要可以通過配置useUnfairLock屬性為true使用非公平鎖。
          ??????max-wait:?60000
          ??????#?是否緩存preparedStatement,也就是PSCache。PSCache對支持游標的數據庫性能提升巨大,比如說oracle。在mysql下建議關閉。
          ??????pool-prepared-statements:?false
          ??????#?指定每個連接上PSCache的大小,要啟用PSCache,必須配置大于0,當大于0時,poolPreparedStatements自動觸發(fā)修改為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
          ??????#?是否在獲得連接后檢測其可用性,連接時執(zhí)行validationQuery檢測連接是否有效,做了這個配置會降低性能。
          ??????test-on-borrow:?false
          ??????#?是否在連接放回連接池后檢測其可用性,做了這個配置會降低性能。
          ??????test-on-return:?false
          ??????#?是否在連接空閑一段時間后檢測其可用性,建議配置為true,不影響性能,并且保證安全性。申請連接的時候檢測,如果空閑時間大于timeBetweenEvictionRunsMillis,執(zhí)行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
          ??????#?屬性類型是字符串,通過別名的方式配置擴展插件,常用的插件有:監(jiān)控統(tǒng)計用的filter:stat,日志用的filter:log4j,防御sql注入的filter:wall
          ??????filters:?stat

          ??????##########??StatViewServlet監(jiān)控配置??##########
          ??????stat-view-servlet:
          ????????login-username:?guoheng
          ????????login-password:?guoheng
          ????????allow:
          ????????deny:
          ??aop:
          ????auto:?true

          ??###################??redis配置??###################
          ??redis:
          ????host:?127.0.0.1
          ????port:?6379
          ????password:
          ????jedis:
          ??????pool:
          ????????max-active:?8
          ????????max-wait:?-1
          ????????max-idle:?8
          ????????min-idle:?0
          ????????time-between-eviction-runs:?30000

          ??###################?sa-token配置?###################
          sa-token:
          ??#?token名稱?(同時也是cookie名稱)
          ??token-name:?satoken
          ??#?token有效期,單位s?默認30天,?-1代表永不過期
          ??timeout:?2592000
          ??#?token臨時有效期?(指定時間內無操作就視為token過期)?單位:?秒
          ??activity-timeout:?3600
          ??#?是否允許同一賬號并發(fā)登錄?(為true時允許一起登錄,?為false時新登錄擠掉舊登錄)
          ??is-concurrent:?true
          ??#?在多人登錄同一賬號時,是否共用一個token?(為true時所有登錄共用一個token,?為false時每次登錄新建一個token)
          ??is-share:?false
          ??#?token風格
          ??token-style:?simple-uuid
          ??#?是否輸出操作日志
          ??is-log:?false


          mybatis:
          ??mapper-locations:?classpath*:mapper/*.xml

          接下來是很重要的兩個sa-token的config(使用過濾器的路由鑒權)

          PS:攔截器鑒權N多坑,不傳satoken也能訪問接口

          特別注意路由一定要有區(qū)分性,例如:/user/user/{id} 這種方式satoken框架認為是同一個路由?。е侣酚设b權將兩個權限碼合并認證

          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全局過濾器]
          ?????*/

          ????@Bean
          ????public?SaServletFilter?getSaServletFilter()?{
          ????????return?new?SaServletFilter()

          ????????????????//?指定?[攔截路由]?與?[放行路由]
          ????????????????.addInclude("/**").addExclude()

          ????????????????//?認證函數:?每次請求執(zhí)行
          ????????????????.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);
          ?????//?路由一定要有區(qū)分性
          ????????????????????SaRouter.match("/user",?()?->?StpUtil.checkPermission("0001"));
          ????????????????????SaRouter.match("/user/get/{id}",?()?->?StpUtil.checkPermission("001101"));

          ????????????????})

          ????????????????//?異常處理函數:每次認證函數發(fā)生異常時執(zhí)行此函數
          ????????????????.setError(e?->?{
          ????????????????????return?Result.failure(e.getMessage());
          ????????????????})

          ????????????????//?前置函數:在每次認證函數之前執(zhí)行
          ????????????????.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?{
          ????@Autowired
          ????UserMapper?userMapper;

          ????@Autowired
          ????UserRoleMapper?userRoleMapper;

          ????@Autowired
          ????RoleMapper?roleMapper;

          ????@Autowired
          ????PermissionMapper?permissionMapper;

          ????@Autowired
          ????RolePermissionMapper?rolePermissionMapper;
          ????@Override
          ????public?List?getPermissionList(Object?userId,?String?s)?{
          ????????//?用戶存在,查找角色
          ????????QueryWrapper?userRoleQueryWrapper?=?new?QueryWrapper<>();
          ????????userRoleQueryWrapper.eq("user_id",?userId);
          ????????List?userRoles?=?userRoleMapper.selectList(userRoleQueryWrapper);

          ????????//?角色查找權限
          ????????QueryWrapper?rolePermissionQueryWrapper?=?new?QueryWrapper<>();
          ????????rolePermissionQueryWrapper.in("role_id",?userRoles.stream().map(UserRole::getRoleId).collect(Collectors.toList()));
          ????????List?rolePermissions?=?rolePermissionMapper.selectList(rolePermissionQueryWrapper);

          ????????QueryWrapper?permissionQueryWrapper?=?new?QueryWrapper<>();
          ????????permissionQueryWrapper.in("id",?rolePermissions.stream().map(RolePermission::getPermissionId).distinct().collect(Collectors.toList()));
          ????????List?sysPermissions?=?permissionMapper.selectList(permissionQueryWrapper);

          ????????List?permissions?=?sysPermissions.stream().map(SysPermission::getCode).distinct().collect(Collectors.toList());
          ????????return?permissions;

          ????}

          ????@Override
          ????public?List?getRoleList(Object?userId,?String?s)?{
          ????????//?用戶存在,查找角色
          ????????QueryWrapper?userRoleQueryWrapper?=?new?QueryWrapper<>();
          ????????userRoleQueryWrapper.eq("user_id",?userId);
          ????????List?userRoles?=?userRoleMapper.selectList(userRoleQueryWrapper);

          ????????//?查詢角色
          ????????QueryWrapper?sysRoleQueryWrapper?=?new?QueryWrapper().in("id",?userRoles.stream().map(UserRole::getRoleId).collect(Collectors.toList()));
          ????????List?sysRoles?=?roleMapper.selectList(sysRoleQueryWrapper);
          ????????List?roleNames?=?sysRoles.stream().map(SysRole::getRoleName).distinct().collect(Collectors.toList());
          ????????return?roleNames;
          ????}
          }

          打這里認證鑒權就完成了,快把,趕緊來測試一下吧。

          學習資料:Java進階視頻資源

          還有一個配置文件沖突的問題,之前我在webMvc里面配置的有靜態(tài)文件讀取和跨域等,與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
          ?????*/

          ????@Override
          ????public?void?addCorsMappings(CorsRegistry?registry)?{
          ????????registry.addMapping("/**")
          ????????????????.allowedOrigins("*")
          ????????????????.allowedMethods("POST",?"GET",?"PUT",?"DELETE",?"OPTIONS")
          ????????????????.maxAge(3600)
          ????????????????//?是否允許發(fā)送Cookie
          ????????????????.allowCredentials(true)
          ????????????????.allowedHeaders("*");
          ????}

          ????@Override
          ????public?void?addResourceHandlers(ResourceHandlerRegistry?registry)?{
          ????????//?靜態(tài)文件
          ????????registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
          ????????//?swagger
          ????????registry.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

          推薦文章


          1、一款高顏值的 SpringBoot+JPA 博客項目

          2、超優(yōu) Vue+Element+Spring 中后端解決方案

          3、推薦幾個支付項目!

          4、推薦一個 Java 企業(yè)信息化系統(tǒng)

          5、一款基于 Spring Boot 的現代化社區(qū)(論壇/問答/社交網絡/博客)

          瀏覽 65
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美成人精品欧美一级私黄 | 人人爽人人超 | 插入小逼网站 | 狠狠狠久久久 | 欧洲A级成人淫片免费看 |