建议本篇结合一年半前的两篇文章食用:
上述两篇是在2018年9月的时候写的,现在回过头来看看好像也没有太多的问题。
其实关于shiro,想要更系统的学习,我还是推荐一个比较老的系列博客了
开涛的 跟我学shiro系列 真的是经典。
把问题从头到尾,娓娓道来,比较系统,但是对初学者来讲可能比较生硬。
我觉得初学者学shiro的最好方式是在现实的问题中去理解shiro给我们做的,直接上这么一整套接口可能很多人都会懵逼。
不过这并不影响shiro本身设计的优秀,我也曾建议过组内的小伙伴系统的学习shiro,也在组内做过分享,虽然当时分享的效果一般般,但绝对不影响shiro在我心中的地位。
所以每次有小伙伴来面试的时候,只要简历上面提到了shiro,我都会针对性的问一下,可惜的是大部分小伙伴都只是说我们项目中有用到过shiro,但实际底层的一些东西还没有学……
什么是shiro
shiro 是Apache基金会的项目:http://shiro.apache.org/
shiro 与 spring security 并列为java的两大安全框架。
shiro与jwt结合
在shiro里面有一个抽象的概念叫token
,可以理解为中文的”凭证”,个人觉得能够理解shiro里面很多抽象的概念是正确学习shiro的核心。
我们可以使用jwt作为shiro的一种token,那shiro怎么识别jwt呢,先定义好如下的JWTTOKEN类:
1 | /** |
这里偷懒了,直接把getPrincipal
方法和getCredentials
方法都返回了token字符串。这个token字符串就是上篇里面讲到的jwt了。
如果你理解了shiro的思想,那完全可以把这两个方法写成获取shiro里面的部分信息。
那啥时候实例化这个JWTTOKEN呢?这里就用到了Filter。
JWTFITLER
这里我的思路就一个,使用filter,如果识别到请求的head里面有token字段,就尝试实例化一个jwttoken
1 | /** |
那我们这个JWTFilter怎么注入到对应的URL注入器呢?
定义好ShiroFilter
1 | "shiroFilter") ( |
上述代码也不复杂,关键是定义了一个ShiroFilterFactoryBean
的 bean,然后将一个Map类型设置到对应的FilterChainDefinitionMap
中。这样我们的Filter即生效了。
那我们这就能生效了?
当然还需要shiro里面最最核心的一个东西,那就是Realm了。
JWTRealm
1 |
|
上述的support
方法定义好了这个Realm是支持JWTTOKEN的,所以当shiro识别到一个请求里面的token是JWTTOKEN时就会走这个类。
然后两个核心的方法一个定义了对应的token实例可以拿到那些权限,另一个方法定义这个token是否是一个合法的token。
总结
这个流程整体上下来可以理解为Filter每次都会拦截每一个请求,如果请求里面的header里面有token信息,如果有,那尝试实例化一个JWTTOKEN交给shiro,然后shiro会把这个JWTTOKEN交给对应的realm,这里就是JWTREALM,在realm里面进行验证合法性操作。
所以其实这个realm的doGetAuthenticationInfo
方法其实是每次登陆都会调用的一个方法,所以一定要做好缓存处理。