V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
nonesuccess
V2EX  ›  程序员

系统规模大了之后,想拆分开再弄个单点登录,求好方案好主意

  •  
  •   nonesuccess · 2016-01-09 22:51:01 +08:00 · 4742 次点击
    这是一个创建于 3031 天前的主题,其中的信息可能已经有所发展或是发生改变。

    还是 xx 管理系统,业务越做越多,子系统之间基本上没有实时数据交互。

    现在的情况就是一个 war 包扔到 tomcat 上撑着,想改个 Java 代码中的常量都得打包重新发布然后做一堆冒烟测试还小心翼翼的。不同子系统之间也是各小组分别开发,互相的沟通也有问题。

    其实各子系统之间的数据交互和流程交互并不多,只不过用户信息是共享的,不能让用户切换子系统时还要重新登录一次。所以我的想法是,*弄个登录服务器存放用户信息和权限信息,其余的子系统分别部署*。底层也是共享一个数据库的,如果有什么交互的地方直接写库就行了,最主要的是先解决不同组能分别开发分别部署的问题。

    那么,这是个好主意吗?另外,这算不算是个单点登录的需求,系统是 JavaEE , struts2 ,有没有合适的方案能做这个东西的?

    现在的登录就是基于 http session ,自己写 filter 实现的。翻过一些帖子,知道有 oauth2 这个方案,但还没有着手调试那些 Java 实现。 spring security 、 shiro 这些东西也看过一点,不清楚是不是可以做这个事情。另外一种方案就是自己去实现 refresh token , access token 那些东西,没有能力研究网络安全机制,拿成熟方案自己实现应该问题不大。

    技术选型方面的主要需求就是不要对现有架构改动太大。

    大家的项目做大了之后都是怎么搞定的?

    16 条回复    2016-01-12 22:49:14 +08:00
    domty
        1
    domty  
       2016-01-10 02:49:34 +08:00
    把登录功能单独分拆一个功能,返回用户登录信息,这个功能只能内部服务及子服务访问。

    其他服务照常获取 session 中的登录状态,只有当登录的时候才和登录功能的接口进行通讯,登录成功登录信息入 session 。
    vivisidea
        2
    vivisidea  
       2016-01-10 10:28:25 +08:00
    要实现“不能让用户切换子系统时还要重新登陆一次”这个效果,我想了下可以这样

    1. 单独部署一个登陆中心 login.xx.com ,认证成功之后直接写加密的 cookie
    2. 各个子系统直接从 cookie 中读取认证信息,校验通过,就认为登陆,不通过就 redirect 到登陆中心认证

    校验可以由 login.xx.com 提供校验接口,也就是把 cookie 丢回给 login.xx.com 让这个模块统一校验
    vivisidea
        3
    vivisidea  
       2016-01-10 10:36:07 +08:00
    我看了下像新浪微博之类的应该就是这么做的,比如 weibo.comvdisk.weibo.com 是不需要重新登陆的, sso cookie 直接写在.weibo.com 这个 path 下,这样子 xx.weibo.com 也能读取到这个 cookie
    xujif
        4
    xujif  
       2016-01-10 12:18:39 +08:00 via iPhone
    新浪微博是标准的 cas 实现吧
    xujif
        5
    xujif  
       2016-01-10 12:20:25 +08:00 via iPhone
    单点登录简单点就 cookie 共享,缺点是不够安全,不能跨域。靠谱点就上 cas , oauth ,用作登录这两个没什么不同
    misaka14
        6
    misaka14  
       2016-01-10 14:16:31 +08:00
    珍爱生命,远离 cas
    micookie
        7
    micookie  
       2016-01-10 18:12:08 +08:00
    见过一个单点登录,是通过模拟提交表单实现的。。。。
    wph95
        8
    wph95  
       2016-01-10 18:37:55 +08:00
    google 查 SSO
    //用 token 也不是很麻烦
    nonesuccess
        9
    nonesuccess  
    OP
       2016-01-10 20:20:53 +08:00
    @xujif 现在就是在同一个域下,安全性上 cookie 共享也应该不是什么大问题,只是不知道具体的实现思路

    子系统那边,请求来了之后先判断 cookie 中有没有登录 token ,如果没有或者已经失效,就重定向到登录服务器,登录成功后,由登录服务器写 cookie ,然后再重定向回原地址,后面走的就是 cookie 中有 token 的分支了。

    cookie 中有 token 时,不知道该怎么搞了。

    感觉应该在某一步骤由登录服务器给子系统服务器一个用户权限信息,是在服务器写 cookie 中的 token 之后吗?如果是这样的话,还要共享 cookie 有什么意义呢?

    求指教
    nonesuccess
        10
    nonesuccess  
    OP
       2016-01-10 20:21:25 +08:00
    @vivisidea 同楼上,求共享 cookie 的方案
    nonesuccess
        11
    nonesuccess  
    OP
       2016-01-10 20:24:24 +08:00
    @vivisidea

    --校验可以由 login.xx.com 提供校验接口,也就是把 cookie 丢回给 login.xx.com 让这个模块统一校验

    两个疑问:

    一是每个请求都要让 login 服务器验证一次吗
    二是 cookie 给 login 服务器的方式是服务端交互吗,如果是的话,那 login 服务器在客户端写 cookie 的意义是什么,直接在子系统服务器上维护一个 session 和用户 id 的对应关系,再用这个用户 id 去 login 服务器去取数据不就可以了吗,如果不是的话,那又是什么实现细节?
    nonesuccess
        12
    nonesuccess  
    OP
       2016-01-10 20:24:34 +08:00
    @misaka14 和解?
    vivisidea
        13
    vivisidea  
       2016-01-10 21:05:18 +08:00
    @nonesuccess 我见过在本地验证的, cookie 里有基本信息(用户名之类的),验证的逻辑打成一个 jar 包,不过感觉不太安全~~确实是每个请求都检查一遍 cookie 的有效性

    发回给 login 的方案是我猜想的,我设想是不是认证通过之后应用自己也写一个自己的 session cookie ,请求来的时候先检查 application 的 cookie ,如果不对再检查 sso 的 cookie ,这样是不是就不用每次都发回去检查了
    cnhongwei
        14
    cnhongwei  
       2016-01-11 09:56:20 +08:00
    还是使用 oauth 方便一些,一是不存在共享 cookie 的问题。
    二是解决了你“为什么要共享 cookie ”的问题,各系统还是自己使用自己的 cookie 或 session ,登录服务器只是完成登录,并将用户的信息返回给各子系统,由各子系统自己处理。
    当然 oauth 只处理登录,不管各子系统的权限等,所以还得看你自己的需求,有些 sso 系统还有统一的权限拦截器,可以处理统一的权限,不过,我是不太赞同,因为个人认为统一权限弊大于利。
    xujif
        15
    xujif  
       2016-01-11 11:53:04 +08:00
    @nonesuccess 没必要每个请求都校验,这样 sso 服务器压力太大。
    子系统维护自己的 session,并使用一个 filter 监听退出请求。登陆时定向到 sso 完成登录,退出时由 sso 服务器统一发出登出请求到各个子系统,子系统完成 session 销毁。
    oauth 协议只能完成单点登录部分,不能完成 单点退出 这个需求。
    cas 本身基于 url 保护的 filter 都是现成的。
    其实不管怎么说, sso 登录都有 cas 的影子, cas 不止是一个软件,而是一个协议标准了。
    楼下那位远离 cas 我不知道怎么做到的。
    misaka14
        16
    misaka14  
       2016-01-12 22:49:14 +08:00
    @nonesuccess 只是简单实现 sos 登录,退出登录当然简单。如果你网站有多个角色,那就头大了,还有新浪是在源代码基础上,自己改写了好多。如果有多个 tomcat,再用个 hadproxy 转发什么的,会存在 session 莫名丢失等莫名其妙的 BUG ,我已经半年以上没做了,有点忘记了哪些更详细的 BUG 。
    还有一点不清楚,为什么改了 java 文件,不先把编译成 class 文件,把这个记录下来,再到服务器替换,再把之前 class 文件先备份一遍,如果出问题,直接查看修改了哪些 java 文件,问题不是很好地定位吗
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5349 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 09:33 · PVG 17:33 · LAX 02:33 · JFK 05:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.