SpringBoot + Shiro + Redis + JWT 实现无状态登录

这是一篇随笔和心得,不会写入任何的一种代码。只是提供一种逻辑。

在我之后,我会发现这种逻辑尤为重要


最近在做一套通用的权限管理项目,考虑使用的是Shiro 的这个框架。认证和鉴权就是权限框架所解决的问题。

对于认证,使用默认的SecurityManager时 Shiro 采用的是将所有的Session信息写入到内存中,来维持会话信息。详情可以看 DefaultSessionManager

DefaultSessionManager 中使用的是基于内存的Session 管理机制,由于面向对象若自己定义的Session管理类继承了其中的某个Session管理类。对于类的初始化皆有调用构造器时隐式的调用父类的构造器进行先初始化

所以对于会话的管理,则转移到了如何对于内存中session的管理,单机情况下用户的注销。在调用注销后,则可以通过使内存中的session失效来实现。

但是在集群环境中并不适合。所以需要通过一种方式来将session持久化保存到一个地方便于session的管理。

这里选用的是redis 并且重写了SessionDao 并且注入容器中用于操作Session

继承并且重写SessionManager 中的GetSessionId方法, 在每次的请求头中获取某一个指定前缀的Token

如果获取不到的话 则调用父类的从Cookie中获取。

由于指定了SecurityManager 中的缓存管理器和UserRealm中的缓存管理器为Redis的CacheManage

所以在用户的登录后的信息,以及用户第一次访问需要权限的资源信息时会调用自定义realm中的授权方法,来校验用户是否有对应的权限。

而如果确定用户是否可以访问不同的权限呢? 在每一次用户获取权限信息时根据不同的业务逻辑将不同的权限字符串或者角色字符串授予指定的角色或者用户即可。

那么在更新用户的权限信息时,由于redis中的权限信息并不会被更新,所以可以对redis中的信息设置某个前缀,在对其进行授后,使其信息失效。这样被授权方,不需要重新登录。在下次访问授权资源的时候则会重新查询数据库权限。

 

 

2、第二种方法则是通过jwt 来做校验

jwt做校验的逻辑其实和上述差不多,可以把权限信息放到jwt中在用户访问的时候对其进行解密。 这样服务端则不需要来维护用户的权限信息。

shiro 关闭产生会话,则在用户登录成功后 颁发jwt 然后用户在请求中 一般是头部附带jwt信息。

在服务端获取到token后对其进行解密,然后去访问服务器的资源。

后面的话不想多说了, 某位大佬一句话说的好,就是你想什么是jwt? 它是用来解决什么问题的? 有什么好处? 有什么弊端?

 

posted @ 2020-07-23 17:55  站在山顶的人  阅读(982)  评论(0编辑  收藏  举报