zoukankan      html  css  js  c++  java
  • 如何设计一个单点登录系统(3)?

    在上一篇文章

    如何设计一个单点登录系统(2)?

    中主要讲解了可跨域SSO系统服务端,客户端在登录,登出过程中分别应该承担的职责,本文将重点聊一下具体技术实现,源码地址: https://github.com/zhoudapeng/zsso

    首先聊服务端的实现,毕竟服务端是整个单点登录系统的大脑

    1. 提供登录页,这个是登录的基础,所有的接入方在发现当前用户未登录的情况下都会重定向到sso服务端的登录页,服务端的逻辑如下:

    如何设计一个单点登录系统(3)?

    sso服务端登录页逻辑

    这里服务端需要做个判断:

    • 如果当前登录存在.sso.com域下的有效cookie,则证明此用户之前在其他业务系统登录过,此时无需再让用户登录,只需要绑定token与此系统名的关系,然后重定向到此系统的回调接口(接入方需要在此回调接口中验证token,创建本地会话)

    • 不存在.sso.com域下的有效cookie,证明此用户未登录过,需要跳转到登录页,让用户登录,为了用户登录后能直接进入之前的页面,这里重定向的过程中需要带上redirectUrl 这个参数

    2.提供登录接口,用户在登录页输入账号密码后会通过form表单已post的形式提交到此接口

    如何设计一个单点登录系统(3)?

    sso服务端登录form表单提交处理逻辑

    • 如果账号密码不对,则再次跳转到登录页

    • 账号密码匹配,则需要创建token,绑定token与系统名的关系,写全局cookie,然后重定向到接入方的回调地址

    3.提供验证token接口

    如何设计一个单点登录系统(3)?

    sso服务端验证token接口

    • token不存在,返回验证失败

    • token存在,则取出token的有效截止日期,并绑定token与系统名的关系

    4.提供登出接口

    如何设计一个单点登录系统(3)?

    sso服务端登出接口

    登出时,需要根据token查到所有绑定过的系统名,然后调用各个系统的登出接口一一登出。

    以上是服务端需要提供的4个接口,下面我们再将一下客户端的实现

    在第一篇文章中讲过,一个好的sso系统必须要让接入方接入简单,所以本人借鉴了spring auto-driven的思想,也提供了对应的命名空间,并抽象出了UrlHelper,UserStore,ZssoClient,ZssoConfigResolver4个组件,以及默认实现类,接入方在接入过程中可以随意拓展这4个组件,然后直接注入到业务层上下文即可。

    • UrlHelper:拼接url的组件,如无特殊需求不建议重新实现

    • ZssoClient:跟服务端交互的组件,如无特殊需求不建议重新实现

    • ZssoConfigResolver:解析配置文件的组件,默认实现是读取本地classpath下zsso-client.properties配置文件,如无特殊需求不建议重新实现

    • UserStore:存取用户信息的组件,包括根据token解析用户信息,绑定token与userId关系,解绑token,默认实现只是为了演示用,接入方请务必自己实现此接口,并以userStore的名称注入到业务层上下文中。

    拓展组件使用方式:

    如何设计一个单点登录系统(3)?

    拓展UserStore组件配置方式

    在spring扫描掉<zsso:auto-driven/>时会去回调ZssoNamespaceHandler的init方法,最终执行ZssoBeanDefinitionParser的parse方法,在此方法中会去检查每个组件是否有注入对应的BeanDefinition,如果没有则会自动注入默认实现类,核心代码如下:

    如何设计一个单点登录系统(3)?

    ZssoBeanDefinitionParser核心代码

    如何设计一个单点登录系统(3)?

    ComponentInitializer核心代码

    至此组件初始化的问题已经解决了,另外需要接入方开发的是如下问题:

    1. 判断登录状态

    2. 登录成功回调接口(包括check token的逻辑)

    3. 登出回调接口

    既然每个接入方都有这样的共性,所以我提供了一个ZssoFilter,在Filter里根据不同的url做不同的处理,接入方只需要配置此Filter即可,Filter内部会自动去获取组件,接入方只需要拓展相关组件即可,ZssoFilter核心代码如下:

    如何设计一个单点登录系统(3)?

    ZssoFilter核心逻辑

    LoginCallbackFilter已封装好解析请求参数中token,check token,创建本地会话,跳转到原页面等功能

    LoginCheckFilter已封装好判断当前用户是否登录及跳转到登录页的逻辑

    LogoutFilter已封装好删除本地会话的功能

    代码中很多代码都是演示类的,尤其是server端的实现,比如保持用户信息都是存的本地缓存,如果要放到生成环境则需要优化下这块的逻辑,比如放到redis这样的分布式缓存等等。

    最后非常感谢大家能在百忙中抽空看我的文章,大家的每一次查看都是我继续写文章的动力,由于本人是典型理科男,文笔可能欠妥,希望大家能够继续支持我,我也会继续努力,继续坚持原创,但愿能让大家都能有所收获!

  • 相关阅读:
    jQuery中的一些操作
    laravel使用消息队列
    Laravel的开发环境Homestead的搭建与配置
    python爬虫学习
    配置文件
    sql根据时间差查询数据
    Oracle根据连接字符串获取库下的表列表、获取表结构
    Sql根据连接字符串获取库下的表列表、获取表结构
    判断网络连接
    线程锁,解决多线程并发问题
  • 原文地址:https://www.cnblogs.com/a8457013/p/9055266.html
Copyright © 2011-2022 走看看