首页 > 其他分享 >谈谈项目中单点登录的实现原理?

谈谈项目中单点登录的实现原理?

时间:2023-03-16 15:35:54浏览次数:52  
标签:OpenId 单点 登录 验证 用户 谈谈 子系统

单点登录在现在的系统架构中广泛存在,它将多个子系统的认证体系打通,实现了一个入口多处使用,而在架构单点登录时,也会遇到一些小问题,在不同的应用环境中可以采用不同的单点登录实现方案来满足需求。

共享Session

共享Session是实现单点登录最直接、最简单的方式。将用户认证信息保存于Session中,即以Session内存储的值为用户凭证,这在单个站点内使用是很正常也很容易实现的,而在用户验证、用户信息管理与业务应用分离的场景下即会遇到单点登录的问题,在应用体系简单,子系统很少的情况下,可以考虑采用Session共享的方法来处理这个问题。

受以下约束:

  • Session中所涉及的类型必须是子系统中共同拥有的(即程序集、类型都需要一致),这导致Session的使用受到诸多限制;
  • 跨顶级域名的情况完全无法处理;

基于OpenId的单点登录

这种单点登录将用户的身份标识信息简化为OpenId存放于客户端,当用户登录某个子系统时,将OpenId传送到服务端,服务端根据OpenId构造用户验证信息,多用于C/S与B/S相结合的系统。

  1. 当用户第一次登录时,将用户名密码发送给验证服务;
  2. 验证服务将用户标识OpenId返回到客户端;
  3. 客户端进行存储;
  4. 访问子系统时,将OpenId发送到子系统;
  5. 子系统将OpenId转发到验证服务;
  6. 验证服务将用户认证信息返回给子系统;
  7. 子系统构建用户验证信息后将授权后的内容返回给客户端。

这套单点登录验证机制的主要问题在于他基于C/S架构下将用户的OpenId存储于客户端,在子系统之间发送OpenId,而B/S模式下要做到这一点就显得较为困难。

基于Cookie的OpenId存储方案

Cookie的作用在于充当一个信息载体在Server端和Browser端进行信息传递,而Cookie一般是以域名为分割的,例如a.xxx.com与b.xxx.com的Cookie是不能互相访问的,但是子域名是可以访问上级域名的Cookie的。即a.xxx.com和b.xxx.com是可以访问xxx.com下的Cookie的,于是就能将顶级域名的Cookie作为OpenId的载体。

  1. 在提供验证服务的站点里登录;
  2. 将OpenId写入顶级域名Cookie里;
  3. 访问子系统(Cookie里带有OpenId)
  4. 子系统取出OpenId通过并向验证服务发送OpenId
  5. 返回用户认证信息
  6. 返回授权后的内容

在以上两种方法中我们都可以看到通过OpenId解耦了Session共享方案中的类型等问题,并且构造用户验证信息将更灵活,子系统间的验证是相互独立的,但是在第三种方案里,我们基于所有子系统都是同一个顶级域名的假设,而在实际生产环境里有多个域名是很正常的事情,那么就不得不考虑跨域问题究竟如何解决。

B/S多域名环境下的单点登录处理

在多个顶级域名的情况下,我们将无法让各个子系统的OpenId共享。处理B/S环境下的跨域问题,我们首先就应该想到JSONP的方案。

步骤如下:

  1. 用户通过登录子系统进行用户登录;
  2. 用户登录子系统记录了用户的登录状态、OpenId等信息;
  3. 用户使用业务子系统;
  4. 若用户未登录业务子系统则将用户跳转至用户登录子系统;
  5. 用户子系统通过JSONP接口将用户OpenId传给业务子系统;
  6. 业务子系统通过OpenId调用验证服务;
  7. 验证服务返回认证信息、业务子系统构造用户登录凭证;(此时用户客户端已经与子业务系统的验证信息已经一一对应)
  8. 将用户登录结果返回用户登录子系统,若成功登录则将用户跳转回业务子系统;
  9. 将授权后的内容返回客户端;

安全问题

经过以上步骤,跨域情况下的单点登录问题已经可以得到解决。而在整个开发过程初期,我们采用用户表中记录一个OpenId字段来保存用户OpenId,而这个机制下很明显存在一些安全性、扩展性问题。这个扩展性问题主要体现在一个方面:OpenId的安全性和用户体验的矛盾。

整个单点登录的机制决定了OpenId是会出现在客户端的,所以OpenId需要有过期机制,假如用户在一个终端登录的话可以选择在用户每次登录或者每次退出时刷新OpenId,而在多终端登录的情况下就会出现矛盾:当一个终端刷新了OpenId之后其他终端将无法正常授权。

而最终,我采用了单用户多OpenId的解决方案。每次用户通过用户名/密码登录时,产生一个OpenId保存在Redis里,并且设定过期时间,这样多个终端登录就会有多个OpenId与之对应,不再会存在一个OpenId失效所有终端验证都失效的情况。

 

参考:

 

标签:OpenId,单点,登录,验证,用户,谈谈,子系统
From: https://www.cnblogs.com/xfeiyun/p/17222723.html

相关文章

  • ChatGPT登录显示所在国家/地区不允许访问
    在浏览器地址栏输入avascript:window.localStorage.removeItem(Object.keys(window.localStorage).find(i=>i.startsWith('@@auth0spajs')))在上述代码的头部加上字......
  • android的google三方登录一直返回10
    标题:com.Google.android.gms.common.api.apiException:10:为何一直报错,这个问题的来源是可参考这里的状态码:googleStatusCodes配置其实都很简单,可参考:googleAndroid登录......
  • Linux进入单用户模式:无密码登录root
    进入单用户模式可以做哪些操作:无密码登录root用户,可以修改密码(passwd),可以查看编辑文件等操作Linux进入单用户模式详细请看:https://www.cnblogs.com/sheepboy/p/17218500......
  • Android学习-用子菜单实现不同身份登录页面的切换
    实现了安卓每日打卡APP教师身份的登录,在这部分我选择使用子菜单实现,效果如下:实现代码见后进入APP,默认是学生登录界面:  打开右上角子菜单,选择跳到教师登录界面: ......
  • 爬虫学习02之模拟登录以及代理
    一、调试模式介绍调试模式,即进入网页页面半代码模式,查看网页与代码一一对应关系。鼠标右键,再出现选项中找到检查进入调试模式,或者按键盘上的F12键进入调试模式。功能介......
  • 自定义登录成功处理和失败处理
    自定义登录成功处理和失败处理在某些场景下,用户登录成功或者数失败的情况下用户需要执行一些后续操作,比如登录日志搜集,或者在现在目前前后端分离的情况下,用户登录成功和失......
  • selenium自动化测试-qq邮箱登录
    fromtimeimportsleepfromseleniumimportwebdriverfromselenium.webdriver.common.byimportByfromselenium.webdriver.chrome.optionsimportOptionsoptions=O......
  • 获取当前登录用户
    获取当前登录用户传统web系统中,我们将登陆成功的用户放入session中,在需要的时候,可以从session中获取用户,那么springSecurity中我们可以从以下两个类获得当前已经登录的用......
  • Linux开启root用户远程登录
    Linux开启root用户远程登录开启root账户,给root用户设置密码sudopasswdroot输入两遍密码修改配置文件打开SSH配置文件。vim/etc/ssh/sshd_config修改如下参......
  • centOS 密码正确,无法登录:login incorrect
    root用户密码正确,但是登录时提示:loginincorrect,回想一下无法登录前在系统进行修改文件权限的操作导致出现问题步骤1:进入单用户模式    a.开机启动时,快速按住键......