项目原来是单体架构,现拆分成spring cloud微服务架构。
过程中,整理了一下项目“认证授权”功能的微服务之间的调用思路:
如下两个方法的切入点都是在ShiroConfig配置类(@Configuration)中@Bean注入的:
1 shiroFilterFactoryBean -> JwtFilter中的onAccessDenied()
-> 无token:直接放过
--> 登录/login
---> 远程调用oauth模块
----> 去验证(username,password) + accountService.generateToken()
-----> jwtUtils生成token,返回
--> 其它不需要登录的业务模块
-> 有token:jwtUtils校验token
--> 合法未过期,放过
--> 不合法已过期,重新登录
2 securityManager -> Realm
-> 认证doGetAuthenticationInfo(有token时才会走这个方法)
--> jwtUtils获取userId
---> 远程调用user模块
----> userService查询userInfo,放入上下文中SimpleAuthenticationInfo(便于ShiroUtils.getProfile()获取当前登录的用户信息),返回
-> 鉴权doGetAuthorizationInfo
--> 远程调用Authority(role + permission)模块
---> roleService.byUserId(...)查询role,role查询permission,返回
备注:
这么多天的实践,发现:
由于shiro必须使用web-mvc(依赖spring-boot-starter-web),但是web-mvc与web-flux不兼容。
而springcloud-gateway必须依赖web-flux,所以shiro无法集成到springcloud-gateway,会失效。就算:shiro-spring-boot-web-starter --> <exclusion>spring-boot-starter-web</exclusion>排除掉。这样虽然能启动,但是shiro的所有filter并不会生效!!!
所以大家在网上根本找不到,没有关于“gateway集成shiro”的相关文章,顶多就是:
① gateway之后与应用app之间再额外加一个权限校验层app。(性能瓶颈,多此一举)
② 或者把shiro放到一个common模块中,所有模块都依赖。(相当于所有模块都有集成shiro了,那还叫啥gateway网关统一鉴权,失去了分布式的意义)
总结:
上面这两种方式都不如spring-security直接在gateway上校验权限的方式更令人满意,如此才叫“gateway网关统一认证鉴权”!!