Skip to content
it is easy to use shiro for rest api ~ quick start ~ base on spring boot 2.x
Java
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
demo-redis
demo
shiro-spring-boot-starter
.gitignore
README.md
pom.xml

README.md

写在前面

  • 此starter封装并不只是为了使用完整的Shiro功能,目的是为大家提供一种封装思路,如果实际应用在业务场景,还需要具体情况具体分析
  • 当然你也可以遵循目前的设计规范,如果有功能没有满足,不妨提个issue……
  • 倘若你有自己的设计,fork过去尽情修改吧~

JWT和Session的区别

  • JWT:服务端无状态。所有状态存储在客户端的加密token里面。服务端只负责校验token的有效性。服务端无法强制下线。
  • Session:服务端有状态。客户端只是存储一个sid,服务端存储sid对应的信息。多应用共享Session通常使用Redis之类的内存数据库存储。

登录鉴权方式

  • 使用传统的session方式

SessionId传递

  • sessionId放在header或者cookie进行传递。header的sid具有高优先级。

Spring Boot SPI

Spring Boot SPI 可以代替包扫描的配置 Spring Boot SPI 类似于 Java SPI的加载机制。 META-INF/spring.factories配置:

# 如下:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration

Session的序列化

  • 由于Session都会实现Serializable,所以统一使用JDK的序列化方式,保证稳定性和兼容性。

Redis配置

  • Redis配置完全和spring-data-redis一致,且为默认的RedisTemplate
  • 由于Shiro的序列化方式默认是JDK序列化,如果非Shiro需要使用其他序列化方式,需要单独配置,参考demo-redis。
  • 多Redis数据源配置:此时spring.redis的配置依然需要配置,其他数据源单独配置。

appId

  • appId用于多系统交互时使用,如果系统不涉及此方面,可以忽略。
  • appId可以通过配置文件配置,表示当前系统的app标识
  • 也可以遵循协议,appId通过cookie或者header传递。header具有较高优先级(设计和Session一样)
  • 为什么不放在Session?
    • 因为多系统可能公用一个Session,此时无法判断当前Session属于哪个系统。

配置文件示例

spring:
    redis:
      database: 0
      host: 192.168.0.105
      port: 6379
      password: foobared
      lettuce:
        pool:
          max-active: 8
          max-wait: -1
          max-idle: 8
          min-idle: 0
      timeout: 100s
    maxplus1:
      shiro:
          app:
            id: uuuappkey
            key: MaxPlus1     
          tokenKey: uuusid
          loginUrl: /api/sys/login
          filterChain: | # 注意所有perms的权限都需要通过@RequirePermissions来实现,建议不要配置perms(动态URL问题)。PS:yaml配置map的key含有/时,无法识别/。
              /static/**=anon
              /api/sys/ssoLogin=anon
              /api/sys/login=anon
              /api/sys/testRedis=anon
              /api/**=authc
              /**=authc
              /api/sys/logout=logout
          globalSessionTimeout: 180000000 # 3,600,000 milliseconds = 1 hour
          sessionValidationInterval: 360000 # 会话有效校验扫描间隔
          redisCacheEnabled: false # 开启分布式session 需要引入Redis的相关配置,spring-data-redis
          testMode: false # 开启测试模式,测试模式下所有url的访问权限都是anon
          mockUser: # 测试模式模拟的用户
              userId: 'MOCK_USER0'
              userName: 'mock_yonghu0'
              deptId: 'MOCK_DEPT0'
              deptName: '模拟部门0'
              realName: '模拟用户0'
              status: '正常'
              password: 'MOCK_PASS0'

Filters与AuthorizingAnnotationMethodInterceptor

  • @RequiresPermissions注解的处理是通过AOP实现拦截器PermissionAnnotationMethodInterceptor来处理;而perms是通过filter来实现的:PermissionsAuthorizationFilter
  • Filter与MethodInterceptor的区别,Filter是基于URL做的拦截,而MethodInterceptor是基于AOP直接对方法进行的拦截。对于REST URL,比如/api/user/{id}这样的url请求。
  • Filter处理REST URL需要自己实现Filter并对url进行解析匹配(具体参考spring mvc的url匹配规则,略复杂);或者直接使用MethodInterceptor。

demo测试

  • 启动demo or demo-redis
  • 登录测试(返回SessionId):127.0.0.1:9000/demo/api/sys/login?userName=yonghu0&password=PASS0
  • 访问测试(需要在cookie或者header带上uuusid=sessionId访问):127.0.0.1:9000/demo/api/sys/testAccess
  • 无权限访问测试(需要在cookie或者header带上uuusid=sessionId访问):127.0.0.1:9000/demo/api/sys/testDeny
  • 测试不同的Redis序列化方式:127.0.0.1:9000/demo/api/sys/testRedis

HTTP状态码

  • 未登录被拒绝:401
  • 未授权被拒绝:403

注意

  • 既然基于Shiro做了封装,那么可自定义的模块肯定减少,如果需要增加其他配置。可以:
    • 下载源码自行修改
    • 提issue到github
    • 使用原生Shiro进行个性化的封装
  • com.maxplus1.access.starter.config.shiro.interceptor.shiro.Perms (已废弃)
  • 此包只适配了前后端分离的项目,没有对静态资源进行处理。且Shiro的异常以json形式返回。

deploy

  • 更改parent下的pom.xml的snapshotRepository.urlrepository.url为自己私库的url
  • 配置maven的settings.xml的server标签。如下:
<server>
    <id>user-snapshot</id>
    <username>your name</username>
    <password>your pass</password>
</server>
<server>
    <id>user-release</id>
    <username>your name</username>
    <password>your pass</password>
</server>
  • 执行maven的deploy命令

TODO

  • Session的一级缓存,二级缓存
  • 动态更新权限,刷新缓存
  • 同一账号多处登录问题
  • 账户踢出接口
  • Shiro其他配置
You can’t perform that action at this time.