<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>

          重磅推薦:一款功能強(qiáng)大、非常全面的Java權(quán)限認(rèn)證框架!

          共 25065字,需瀏覽 51分鐘

           ·

          2021-10-26 02:28

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

          details/116692302

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

          官網(wǎng)地址

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

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

          這是他的大致功能點(diǎn),今天我們搞點(diǎn)基礎(chǔ)的

          springBoot 集成sa-token 并實(shí)現(xiàn)登錄的驗(yàn)證和權(quán)限的鑒定

          首先導(dǎo)入maven坐標(biāo)

          導(dǎo)入redis主要是sa-token使用內(nèi)存來存取token的,使用redis第三方來做到重啟項(xiàng)目token不丟,只需導(dǎo)入sa-token-redis的maven即可,不需要手動(dòng)get,set

          <!-- Sa-Token 權(quán)限認(rèn)證, 在線文檔: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默認(rèn)序列化方式) -->
          <dependency>
              <groupId>cn.dev33</groupId>
              <artifactId>sa-token-dao-redis</artifactId>
              <version>1.25.0</version>
          </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:
                # 連接池建立時(shí)創(chuàng)建的初始化連接數(shù)
                initial-size: 1
                # 連接池中最大的活躍連接數(shù)
                max-active: 20
                # 連接池中最小的活躍連接數(shù)
                min-idle: 1
                # 連接時(shí)最大等待時(shí)間,單位毫秒。配置了maxWait之后,缺省啟用公平鎖,并發(fā)效率會(huì)有所下降,如果需要可以通過配置useUnfairLock屬性為true使用非公平鎖。
                max-wait: 60000
                # 是否緩存preparedStatement,也就是PSCache。PSCache對支持游標(biāo)的數(shù)據(jù)庫性能提升巨大,比如說oracle。在mysql下建議關(guān)閉。
                pool-prepared-statements: false
                # 指定每個(gè)連接上PSCache的大小,要啟用PSCache,必須配置大于0,當(dāng)大于0時(shí),poolPreparedStatements自動(dòng)觸發(fā)修改為true。在Druid中,不會(huì)存在Oracle下PSCache占用內(nèi)存過多的問題,可以把這個(gè)數(shù)值配置大一些,比如說100。
                max-pool-prepared-statement-per-connection-size: -1
                # 用來檢測連接是否有效的sql,要求是一個(gè)查詢語句。如果validationQuery為null,testOnBorrow、testOnReturn、testWhileIdle都不會(huì)其作用。(不同數(shù)據(jù)庫不同)
                validation-query: SELECT 'x'
                # 指定連接校驗(yàn)查詢的超時(shí)時(shí)間,單位:秒。
                validation-query-timeout: 1
                # 是否在獲得連接后檢測其可用性,連接時(shí)執(zhí)行validationQuery檢測連接是否有效,做了這個(gè)配置會(huì)降低性能。
                test-on-borrow: false
                # 是否在連接放回連接池后檢測其可用性,做了這個(gè)配置會(huì)降低性能。
                test-on-return: false
                # 是否在連接空閑一段時(shí)間后檢測其可用性,建議配置為true,不影響性能,并且保證安全性。申請連接的時(shí)候檢測,如果空閑時(shí)間大于timeBetweenEvictionRunsMillis,執(zhí)行validationQuery檢測連接是否有效。
                test-while-idle: true
                # 配置間隔多久才進(jìn)行一次檢測,檢測需要關(guān)閉的空閑連接,單位是毫秒。
                time-between-eviction-runs-millis: 60000
                # 配置一個(gè)連接在池中最小生存的時(shí)間,單位是毫秒。
                min-evictable-idle-time-millis: 300000
                # 登陸超時(shí)時(shí)間,單位是秒。
                login-timeout: 3
                # 查詢超時(shí)時(shí)間,單位是秒。
                query-timeout: 3
                # 事務(wù)查詢超時(shí)時(shí)間,單位是秒。
                transaction-query-timeout: 60
                # 異步關(guān)閉連接。
                async-close-connection-enable: true
                # 屬性類型是字符串,通過別名的方式配置擴(kuò)展插件,常用的插件有:監(jiān)控統(tǒng)計(jì)用的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名稱 (同時(shí)也是cookie名稱)
            token-name: satoken
            # token有效期,單位s 默認(rèn)30天, -1代表永不過期
            timeout: 2592000
            # token臨時(shí)有效期 (指定時(shí)間內(nèi)無操作就視為token過期) 單位: 秒
            activity-timeout: 3600
            # 是否允許同一賬號(hào)并發(fā)登錄 (為true時(shí)允許一起登錄, 為false時(shí)新登錄擠掉舊登錄)
            is-concurrent: true
            # 在多人登錄同一賬號(hào)時(shí),是否共用一個(gè)token (為true時(shí)所有登錄共用一個(gè)token, 為false時(shí)每次登錄新建一個(gè)token)
            is-share: false
            # token風(fēng)格
            token-style: simple-uuid
            # 是否輸出操作日志
            is-log: false


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

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

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

          特別注意路由一定要有區(qū)分性,例如:/user和/user/{id} 這種方式satoken框架認(rèn)為是同一個(gè)路由?。?dǎo)致路由鑒權(quán)將兩個(gè)權(quán)限碼合并認(rèn)證

          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()

                          // 認(rèn)證函數(shù): 每次請求執(zhí)行
                          .setAuth(r -> {
                              System.out.println("---------- sa全局認(rèn)證");
                              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"));

                          })

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

                          // 前置函數(shù):在每次認(rèn)證函數(shù)之前執(zhí)行
                          .setBeforeAuth(r -> {
                              // ---------- 設(shè)置一些安全響應(yīng)頭 ----------
                              SaHolder.getResponse()
                                      // 服務(wù)器名稱
                                      .setServer("sa-server")
                                      // 是否可以在iframe顯示視圖:DENY=不可以 | SAMEORIGIN=同域下可以 | ALLOW-FROM uri=指定域名下可以
                                      .setHeader("X-Frame-Options""SAMEORIGIN")
                                      // 是否啟用瀏覽器默認(rèn)XSS防護(hù): 0=禁用 | 1=啟用 | 1; mode=block 啟用, 并在檢查到XSS攻擊時(shí),停止渲染頁面
                                      .setHeader("X-Frame-Options""1; mode=block")
                                      // 禁用瀏覽器內(nèi)容嗅探
                                      .setHeader("X-Content-Type-Options""nosniff")
                              ;
                          });

              }

          }

          這里是設(shè)置登錄用戶權(quán)限和角色的地方(從權(quán)限\角色表中查詢放置),這里我只校驗(yàn)了權(quán)限,沒有校驗(yàn)角色

          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: 用戶登錄賦予相應(yīng)權(quán)限
           * @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<String> getPermissionList(Object userId, String s) {
                  // 用戶存在,查找角色
                  QueryWrapper<UserRole> userRoleQueryWrapper = new QueryWrapper<>();
                  userRoleQueryWrapper.eq("user_id", userId);
                  List<UserRole> userRoles = userRoleMapper.selectList(userRoleQueryWrapper);

                  // 角色查找權(quán)限
                  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;

              }

              @Override
              public 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;
              }
          }

          打這里認(rèn)證鑒權(quán)就完成了,快把,趕緊來測試一下吧。

          學(xué)習(xí)資料:Java進(jìn)階視頻資源

          還有一個(gè)配置文件沖突的問題,之前我在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放進(jìn)header里取請求需要權(quán)限的接口

          沒有權(quán)限

          擁有權(quán)限

          還在用Spring Security?推薦你一款使用簡單、功能強(qiáng)大的權(quán)限認(rèn)證框架

          瀏覽 174
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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Ⅴ一区t二区三区 | 亚洲男人的天堂视频网在线观看+720P | 一级A片黃色A片 | 影音先锋 一区二区三区 | 九一大鸡巴 |