| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> 单点登录(SSO)原理以及代码分析 -> 正文阅读 |
|
[系统运维]单点登录(SSO)原理以及代码分析 |
什么是单点登录:? ? ? ? 简单概括就是,对于一个系统有多个应用(淘宝有淘宝,天猫)的情况,用户只需登陆一次,就可以访问所有该系统下的其它应用(登录了淘宝后,跳转到天猫也不用登陆了)。 登录的问题:? ? ? ? 首先要知道,登录的目的是为了访问某些受保护资源,或执行一些特殊权限。 ? ? ? ? 网站传输的是http协议,而http协议是无状态的,即只通过http连接无法判断用户的登录状态的。举个例子:用户在登录页面进行登录("/login")之后跳转到主页("/index"),而主页又是一个新的http连接,此时主页已经不知道用户是否登录了,所以如果执行某些操作时仍需要获取用户的账号,密码等信息。我们当然可以通过url携带参数的模式传递信息,进行验证,但是这个方式对于用户太不友好了。目前的解决方案是:引入Cookie,Session机制。 Cookie-Session机制:? ? ? ? 网站可以通过cookie,session机制来存储用户的登陆状态。 ????????cookie是存储在客户端(用户的浏览器)的,当用户访问网站进行登录后,网站就会给当前用户颁发一个Cookie,在该Cookie有效期内,用户再次访问这个网站时,服务器会验证当前Cookie是否合法,从而减少了用户重新登陆的可能性。 ? ? ? ? session则是一个概念,或者说是一种机制,之所以要跟cookie一起讨论是因为,一般session机制的实现都是在cookie中存储一个 k-v结构的JSEESIONID。你可以F12查看一下,大多数网站都有。可以理解为,用户建立连接->发送cookie->服务端验证 这个过程,称之为session会话。用户在第一次登陆后,服务器端就会为该用户创建一个session,并分配一个独一无二的JSESSIONID,将JSESSIONID以cookie形式传给浏览器。 ? ? ? ? 当然并非只有这一种解决http无状态的方案,而且cookie session机制同样有许多缺点,而单点登录就是基于其中一个缺点而出现的。 多系统模式下的Cookie域问题:? ? ? ? 最基础的cookie-session机制只能解决单体服务的登录模式,而现在的大部分的服务系统都是多系统模式,如CSDN的主页是:www.csdn.net,而个人信息页是:www.blog.csdn.net,学过计算机网络的同学应该可以看出来,两者的域名是个父子关系。这种情况下,依然用不上单点登录,我们可以通过设置cookie的作用域(domain)来解决问题。如:把所有*.csdn.net的作用域全都设置为csdn.net,这样,所有csdn.net的子域名都可以获取到这个cookie。但这是对于存在父子关系的服务情况,而另外的一个情况:淘宝的域名是:taobao.com,而天猫的域名是:tmall.com。但是这两者都属于淘宝的业务,而如果我们要实现的就是在淘宝上登录之后,天猫就也自动登录的效果,就无法使用之前的方案了,因为这两者的域名,没有任何关系。至此,引出了单点登录。 ?单点登录(SSO): ? ? ? ??既然已经知道了问题所在,那么我们解决的思路是什么呢? ? ? ? ? 建立一个所有系统公共的登录认证中心(sso-server),用户在访问任意一个子系统受保护资源时都需要去sso-server去认证。 ????????首次访问A->A发现用户没登陆->跳转到sso-server认证->认证失败->引导至登陆页面->用户输入账号密码进行登录->sso-server校验账号密码->授权令牌->返回到子系统页面->拿到令牌再去sso-server认证->认证成功->登录成功。 ? ? ? ? 此时,sso-server与该子系统之间维护了一个局部会话,sso-server与用户之间维护了一个全局会话。 ? ? ? ??用户访问其它系统B,B发现用户没登录->跳转到sso-server->sso-server认证成功,返回令牌->B拿到令牌,再去sso-server校验->校验通过,允许访问受保护资源。 ????????此时,sso-server与B系统也维护了一个全局会话。? 允许我偷个图: ? ? ? ? ? ? ? ? ? ? ? ?? 需求分析+编写代码:? ? ? ? 我们至少需要启动两个server,一个作为子系统,一个作为sso-server,才能体现出单点登录。 ? ? ? ? 我们需要一个拦截器,在访问子系统受保护资源时进行拦截,判断登陆状态,是否跳转到认证中心。 前端页面:随便写写,主要是我也不会。 用户访问主页面过程: ? ? ? ? 首先启动sso-server服务(8080端口)作为认证中心,再启动demo服务(8082端口)作为子系统。 ? ? ? ? 访问localhost:8082:/,也可以自己写俩域名,不重要。 ? ? ? ? 拦截器启动,拦截"/"请求,判断登录状态。 ? ? ? ? 首先,尝试获取本地Session中的accesstoken,若该token存在,说明最近登陆过,直接放行;否则,尝试获取授权码code,若授权码存在,说明认证中心最近被登陆过,可以通过code来生成一个自己的accesstoken,然后放行;若两者都不存在,说明是第一次访问,重定向到sso-server的登录("/login")页面(记住携带参数,方便我们登录认证完成后回到demo的index页面)。 ? ? ? ? 到了sso-server的login页面后,输入账号密码,做一个简单的校验(没使用数据库,项目重点不在这),点击登录,校验成功后,尝试从浏览器中获取cookie,如果不存在则创建一个并存入浏览器中。接着创建授权码code,并将授权码存入本地变量(可以设置一个过期时间)。然后令url携带授权码信息,重定向回原来的页面(即demo的index)。 ? ? ? ? 回到index后又触发拦截器,同样判断accesstoken与code,此时前者仍为null,但后者已经创建成功被添加在url上;因此我们需要通过code码来获取一个accesstoken,这里使用Oauth2协议,所以url中会添加oauth参数,整体格式如下: ? ? ? ? 接着模拟一个http请求,?将paramMap中所有参数拼接到url上,并访问这个url。 ? ? ? ? 得到的result是一个json格式数据,解析该数据,并将重要参数存储到本地,然后使用这些参数(约定好的appid和appsecret),来生成一个本地token,同时记录本地session和token的映射。 ? ? ? ? 最后,为了回到原来的地址(现在的地址包含了各种授权码参数等),再做一次重定向,重定向并渲染元素到demo的index页面。至此,访问成功。 访问sso-server的index,模拟单点登录 ? ? ? ??直接输入8080:/,被拦截器拦截,尝试获取accesstoken和code,都获取失败(因为是其他网页的请求),接着被重定向到sso-sever的login页面, ????????但是!重点! ? ? ? ? 因为上次demo登录已经生成了cookie并存储在本地!所以直接验证cookie即可,不需要再输入账号密码登录,用户看不到登录页面! ? ? ? ? 直接去创建code和accesstoken,步骤跟demo的基本一致。最终实现,单点登录 ? ? ? ? 之后在服务开启的情况下随便刷新页面,都会在判断accesstoken时直接放行通过。 ? |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/16 2:26:24- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |