• 根据CAS协议写的简单的SSO框架



     
    前言:
    考虑到现在分布式应用都不可或缺的一个重要部分:单点登录,决定花点时间去学下。本来想直接上现成的CAS框架的,初步的了解了一下后,觉得这个太庞大了,而且不好定制,要完全深度用起来也没那么简单(虽然可能上手容易)。于是脑袋一热,决定自己根据CAS协议自己实现一个(虽然不是很喜欢CAS,但CAS协议还是完全的SSO的标准),开始后前后各种被打断,工作啦,加班啦,花时间解决自己的终身大事啦,拖拖拉拉到现在终于初步得已实现。但是现在还仅仅是实现,尚有很多待优化的部分,由于个人工作还是比较忙的,所以就不去完善了。代码我会放到github,有兴趣的完全可以基于它去提交你们的更新,当然,也可以直接留言跟我说需要改进的地方。废话就到这里,下面直接进入主题。
     
     
    技术栈:
    • SpringMVC
    • Filter
    • Listener
    • Cookie/Session
    • Redis/Spring Data Redis
    • HttpClient
     
    架构&流程:
    a:拦截请求
    b:跳转到SSO-Server进行登录
    c:返回token
    d:验证token
    e:验证成功,写入cookie
    f:返回资源页面
     
     
    项目组件介绍:
    • bounter-sso(项目根目录)
    • sso-server(sso服务器,主要负责登录、token验证、刷新token时间、登出)
    • sso-client(sso客户端,主要负责拦截请求,跟sso服务器通信)
    • bounter-app1(虚拟的应用1)
    • bounter-app2(虚拟的应用2)
     
     
    项目运行:
    1. 本地配置虚拟主机(找到hosts文件,加入下面部分)
    127.0.0.1     www.sso.com
    127.0.0.1     www.app1.com
    127.0.0.1     www.app2.com
     
    1. 在jetty中分别启动sso-client、bounter-app1、bounter-app2
     
     
    主要功能:
    • 单点登录
    实现原理几乎完全按照CAS协议,下面是CAS协议的链接:
     
    • Token的集中存储与验证
    本来打算将token保存在sso服务器的session中的,结果发现通过HttpClient进行token验证时,HttpClient生成的请求
    与浏览器的请求是不同的session,因此,token验证时无法获取原浏览器session中的token。最后只能采用redis来集中保存
    token,这样通过HttpClient验证时就能获取到浏览器保存到redis中的token了。顺带也解决了请求过多时服务器session内存消耗太大的问题。
     
    • 单点登出
    主要参考以前CAS源码实现,主要原理大概如下:
      1. 每次有新的会话时,在应用app端保存会话id到一个线程安全的容器中
      2. sso服务器把会话对应的app地址保存到该会话对应的token下,在redis中保存结构如下:
    其中,url包含了不同应用app的sessionid
            3. 应用发出注销请求时,先注销掉本应用自己的session,然后访问sso服务器,清除该会话在服务器对应的token,然后注销服务器session,最后触发服务器session注销的listener
            4. 在处理注销的listener中通过httpclient通知该token对应的所有的应用app根据sessionid参数进行注销,同时移除app端会话容器中保存的会话id
     
    • token失效时间的刷新
    每次建立新的会话时在sso服务器重设redis失效时间,如下:
    //刷新key为sso-token的失效时间  
    stringRedisTemplate.expire(ssoToken,EXPIRE_TIME,TimeUnit.MINUTES);
    后期改进点:
    • 可以把cookie/session改成JWT(Json Web Token)从而实现完全的无状态化和移动端的支持
    • token,jsessionid等的加密与安全
    • 权限控制
     
    源码地址:
  • 相关阅读:
    iOS客户端的gzip解压
    如何将应用打包成.ipa文件(越狱)
    手势UIGestureRecognizer
    ASIHTTPRequest下载数据
    ASIHTTPRequest下载示例(支持断点续传)
    ios与android设备即时语音互通的录音格式
    删除沙盒中文件夹下所有文件
    svn,静态库无法添加
    iOS 3D UI——CALayer的transform扩展解析
    自定义Tabbar实现push动画隐藏效果
  • 原文地址:https://www.cnblogs.com/gdufs/p/6757420.html
Copyright © 2020-2023  润新知