spring+shiro+redis做单点登录,支持分布式部署

#背景: 由于公司前端引进新的技术react,改变了传统的jsp模式,逐渐走上前后端分离的,并且随着小程序,手机端业务的发展,越来越多的项目在开始往上面迁移,这就导致了权限问题。于是也就开启了sso项目,一个人挖坑一个人填,终于是上线了。 #技术选择 没人指引,没人会,导致了我现在百度里面搜索了sso单点登录,当时发现的是有个鉴权验证的,需要第三方服务,cas实现,搞了一天,门都没摸到,淘汰。后来在网上看到有人用shiro来做sso系统,然后开启了shiro的了解之路。 #前言 我介绍更多的是我机遇shiro做的sso项目,对于shiro是啥,网上很多都有介绍,源码我没看,只知道他大概的实现原理,所以本人是小白一名,深入理解不了,见谅。 #sso系统设想 #####登录 当用户登录的时候,登录验证后,把userInfo信息和一个token对应(UUID生成),放入redis中token为key,userInfo为value,并且把token返回给前端,要求前端每次访问数据必须请求头中放token #####鉴权 提供一个HTTP接口,让各个系统都放入到filter里面,每次数据接口请求,需要传递我token以及当前数据请求路径,sso判断是否有权限请求该接口, #需求 sso需要验证登录,需要验证数据请求权限,需要支持分布式部署 #实现 #####登录

  1. 自定义Realm

当调用 SecurityUtils.getSubject().login(ssoUserNameToken)的时候,会调用重写的方法

spring+shiro+redis做单点登录,支持分布式部署

#####鉴权

  1. 自定义PermissionResolver

/**

*

* @param principalCollection

* @return

*/

@Override

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

//该处为伪代码

UserInfo userInfo = (UserInfo) SecurityUtils.getSubject().getPrincipal();

byte[] value = redisClient.get(userInfo.getToken());

if (value != null) {

userInfo = SerializeUtil.deserialize(value, UserInfo.class);

}

String key = SsoConstants.REDIS_ROLE_KEY + userInfo.getToken() + "-" + userInfo.getWebId();

Set allPermissions = new HashSet<>();

byte[] bytes = redisClient.get(key);

SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

info.setStringPermissions(allPermissions);

return info;

}

#####分布式部署 必须重写shiro的sessionDAO的管理,我这个是在github上面,有个大哥写的案例,现在找不到了,很感谢大哥给我的启发

重写类

public class RedisCacheSessionDAO extends AbstractSessionDAO {

//该处需要重写抽象方法

}

#拦截请求 运用shiro的请求拦截,自定义了一些拦截方法

/login/** = anon

/logout/** = logout

/static/**= anon

/** = token,validate,expire

token:验证只能请求token的鉴权路径,其他路径一律拦截返回错误 validate:验证是否有token,token是否有效 expire:延长用户token过期时间 #结束语 以上是我花费1个月研究出来的sso系统,没人做技术指导,有的只是需求,有的只是对技术的执着,我不知道我这种实现方式有什么不妥,目前系统已经上线允许,也许是没人搞我们系统,也许是走了狗屎运,目前运行一切正常。


分享到:


相關文章: