V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
louislivi
V2EX  ›  Java

Spring Boot Shiro+JWT 最简单的整合方式

  •  
  •   louislivi · 2019-12-10 15:07:23 +08:00 · 3584 次点击
    这是一个创建于 1834 天前的主题,其中的信息可能已经有所发展或是发生改变。

    简介

    目前RESTful大多都采用JWT来做授权校验,在Spring Boot 中可以采用ShiroJWT来做简单的权限以及认证验证,在和Spring Boot集成的过程中碰到了不少坑。便结合自身以及大家的常用的运用场景开发出了这个最简单的整合方式fastdep-shiro-jwt

    源码地址

    希望大家可以 star 支持一下,后续还会加入其它依赖的简易整合。 https://github.com/louislivi/fastdep

    引入依赖

    • Maven
    <dependency>
        <groupId>com.louislivi.fastdep</groupId>
        <artifactId>fastdep-shiro-jwt</artifactId>
        <version>1.0.2</version>
    </dependency>
    
    • Gradle
    compile group: 'com.louislivi.fastdep', name: 'fastdep-redis', version: '1.0.2'
    

    配置文件

    • application.yml

      fastdep:
        shiro-jwt:
          filter: #shiro 过滤规则
            admin:
              path: /admin/**
              role: jwt # jwt 为需要进行 token 校验
            front:
              path: /front/**/**
              role: anon # anon 为无需校验
          secret: "6Dx8SIuaHXJYnpsG18SSpjPs50lZcT52" # jwt 秘钥
      #    expireTime: 7200000 # token 有效期
      #    prefix: "Bearer "  # token 校验时的前缀
      #    signPrefix: "Bearer " # token 生成签名的前缀
      #    header: "Authorization" # token 校验时的 header 头
      #    以下对应为 shiro 配置参数,无特殊需求无需配置
      #    loginUrl: 
      #    successUrl: 
      #    unauthorizedUrl: 
      #    filterChainDefinitions: 
      
    • 用户权限配置类

      @Component
      public class FastDepShiroJwtConfig extends FastDepShiroJwtAuthorization {
      
        @Autowired
        private UserRequestDataMapper userRequestDataMapper;
      
        @Override
        public SimpleAuthorizationInfo getAuthorizationInfo(String userId) {
            // 查询该用户下的所有权限(当前为示例仅查询用户 ID 真实环境替换为用户的权限值)
            Set<String> collect = userRequestDataMapper.selectOptions().stream().map(u -> u.getUserId().toString()).collect(Collectors.toSet());
              SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
              System.out.println(collect);
              // 当前值为 [1]
              // 添加用户权限到 SimpleAuthorizationInfo 中
              simpleAuthorizationInfo.addStringPermissions(collect);
              return simpleAuthorizationInfo;
          }
      }
      

    运用

    @RestController
    public class TestController {
        @Autowired
        private JwtUtil jwtUtil;
    
        /**
         * 当前为示例所以直接返回了 token,真实环境为校验登录信息后再返回 token 即可
         * @author : louislivi
         */
        @GetMapping("front/login")
        public String login() {
            // ...校验登录信息是否正确
            // 传入用户唯一标示
            return jwtUtil.sign("1"); 
        }
    
        /**
         * 当前为示例所以权限写的是用户 ID 真实环境替换为权限 key
         * @author : louislivi
         */
        @GetMapping("admin")
        @RequiresPermissions("1")
        public String jwt() {
            return "ok!";
        }
    }
    

    测试

    1.获取token front-login.png

    2.测试权限校验

    • 带 token hasToken.png

    • 不带 token

    {
        "msg": "Access denied !",
        "code": 401
    }
    
    • 带上 token 但是,SimpleAuthorizationInfo中无指定权限
    {
        "msg": "Subject does not have permission [1]",
        "code": 403
    }
    

    扩展

    有时候需要自定义权限校验以及错误返回信息结构等,这时候就需要重写FastDepShiroJwtAuthorization类中的方法。更多详情请看这里

    原理

    使用ImportBeanDefinitionRegistrar BeanDefinitionBuilder.genericBeanDefinition动态注入Bean其实很简单有兴趣可以去看看源码,这样的依赖集成是不是简单了很多呢?

    希望大家能够支持开源,给个小星星,后续还会继续开发其他依赖的整合,甚至兼容其他框架使用。fastdepjava整合依赖更简单。在此也招募有志同道合的coder共同完善这个项目。

    2 条回复    2019-12-11 13:54:26 +08:00
    Oktfolio
        1
    Oktfolio  
       2019-12-10 18:46:03 +08:00
    我更多用 Spring Security
    xingjue
        2
    xingjue  
       2019-12-11 13:54:26 +08:00
    老哥 不搞 swoole 啦
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5884 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 02:10 · PVG 10:10 · LAX 18:10 · JFK 21:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.