单点登录(一)—— 单点登录及常见解决方案原理(CAS、oauth2、JWT)

背景


在企业发展初期,企业使用的系统很少,通常一个或者两个,每个系统都有自己的登录模块,用户用不同的账号即可登录,很方便。
但随着企业的发展,用到的系统随之增多,用户在操作不同的系统时,需要多次登录,而且每个系统的账号都不一样,这对于用户来说,很不方便。于是,就想到是不是可以在一个系统登录,其他系统就不用登录了呢?这就是单点登录要解决的问题。

概念


单点登录英文全称Single Sign On,简称就是SSO。它的解释是:在多个应用系统中,只需要登录一次,就可以访问其他相互信任的应用系统。例如,网页登录了淘宝账号,天猫,钉钉等阿里系应用都不用再二次登录了。 SSO核心意义就一句话:一处登录,处处登录;一处注销,处处注销。就是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统,即用户只需要记住一组用户名和密码就可以登录所有有权限的系统。

可使用一幅图形象表现有误单点登录的系统的区别
在这里插入图片描述

技术实现


基于Cookie的单点登录

这是最简单的单点登录实现方式,是使用cookie作为媒介,存放用户凭证。 用户登录父应用之后,应用返回一个加密的cookie,当用户访问子应用的时候,携带上这个cookie,授权应用解密cookie并进行校验,校验通过则登录当前用户。
不难发现以上方式把信任存储在客户端的Cookie中,这种方式很容易令人质疑:
Cookie不安全
不能跨域实现免登

对于第一个问题,通过加密Cookie可以保证安全性,当然这是在源代码不泄露的前提下。如果Cookie
的加密算法泄露,攻击者通过伪造Cookie则可以伪造特定用户身份,这是很危险的。

对于第二个问题,不能跨域实现免登更是硬伤。因此,有了基于Session的单点登录

基于Session的单点登录

Session解决了Cookie不能跨域的问题,但也存在其他问题。早期的单体应用使用Session实现单点登录,但现在大部分情况下都需要集群,由于存在多台服务器,Session在多台服务器之间是不共享的,因此,还需解决Session共享的问题

解决系统之间的 Session 不共享问题有以下几种方案:

  • Tomcat集群Session全局复制(集群内每个tomcat的session完全同步)【会影响集群的性能呢,不建议】
  • 根据请求的IP进行Hash映射到对应的机器上(这就相当于请求的IP一直会访问同一个服务器)【如果服务器宕机了,会丢失了一大部分Session的数据,不建议】
  • 分布式Session,即把Session数据放在Redis中(使用Redis模拟Session)【建议】

由上可以得出,当前大部分单点登录系统运行流程如下图
在这里插入图片描述

  1. 用户登录系统应用1,发现未登录,重定向到认证系统登录,认证系统验证用户名和密码等信息通过,返回用户一个ticket,并将Session存入Redis或其他缓存容器
  2. 用户携带ticket登录系统应用2,应用系统2到认证系统进行ticket验证,若存在该ticket对应的Session,则登录成功
  3. 用户携带ticket登录系统应用3,应用系统3到认证系统进行ticket验证,若存在该ticket对应的Session,则登录成功

常见方案


CAS

CAS(Central Authentication Service) 是 Yale 大学发起的一个开源项目,是单点登录的一种现方式,分为CAS服务端和CAS客户端
在这里插入图片描述
具体流程如下:

  1. 用户访问app系统,app系统是需要登录的,但用户现在没有登录。
  2. 跳转到CAS server,即SSO登录系统,以后图中的CAS Server我们统一叫做SSO系统。 SSO系统也没有登录,弹出用户登录页。
  3. 用户填写用户名、密码,SSO系统进行认证后,将登录状态写入SSO的session,浏览器(Browser)中写入SSO域下的Cookie。
  4. SSO系统登录完成后会生成一个ST(Service Ticket),然后跳转到app系统,同时将ST作为参数传递给app系统。
  5. app系统拿到ST后,从后台向SSO发送请求,验证ST是否有效。
  6. SSO系统返回验证结果
  7. 验证通过后,app系统将登录状态写入session并设置app域下的Cookie。

至此,跨域单点登录就完成了。以后我们再访问app系统时,app就是登录的。接下来,我们再看看访问app2系统时的流程。

  1. 用户访问app2系统,app2系统没有登录,跳转到SSO。
  2. 由于SSO已经登录了,不需要重新登录认证。
  3. SSO生成ST,浏览器跳转到app2系统,并将ST作为参数传递给app2。
  4. app2拿到ST,后台访问SSO,验证ST是否有效。
  5. SSO系统返回验证结果
  6. 验证成功后,app2将登录状态写入session,并在app2域下写入Cookie。
    这样,app2系统不需要走登录流程,就已经是登录了。SSO,app和app2在不同的域,它们之间的session不共享也是没问题的。
oauth2(第三方登录授权)

OAuth(Open Authorization,开放授权)是为用户资源的授权定义了一个安全、开放及简单的标准,第三方无需知道用户的账号及密码,就可获取到用户的授权信息

主要应用于第三方应用授权登录:在APP或者网页接入一些第三方应用时,时常会需要用户登录另一个合作平台,比如QQ,微博,微信的授权登录,第三方应用通过oauth2方式获取用户信息
在这里插入图片描述
详细步骤如下(以微信登录为例):

  1. 用户访问第三方网站,第三方应用需要用户登录验证,用户选择微信授权登录
  2. 第三方应用发起微信登录授权请求
  3. 微信服务器拉起用户授权确认页面
  4. 用户授权通过
  5. 微信发送请求到第三方应用redirctUrl(第2步填写redirct_uri参数),返回凭证code与state(第2步自定义)
  6. 第三方应用获取到code之后,根据code获取accessToken
  7. 根据accessToken获取用户信息
  8. 对用户信息进行处理(用户是否第一次登录,保存用户信息,自定义token,session处理等)
  9. 返回结果(步骤1对应url或者重定向到首页)
JWT(客户端token)

难度较大,需要了解很多协议
Json web token (JWT),是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标((RFC
7519)。该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。
基于JWT认证协议,自己开发SSO服务和权限控制。

以上为常见的单点登录解决方案,当然,在使用的同时也会和其他的权限授权认证的安全框架整合实现,常见的安全框架有

  • Spring Security
  • Shiro

部分内容引用自
[1] https://yq.aliyun.com/articles/636281
[2] https://www.jianshu.com/p/4f5fcddb4106

  • 12
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: OAuth 2.0是一种授权框架,用于授权第三方应用程序访问用户在其他应用程序上的资源。当用户使用OAuth 2.0登录并授权后,被请求访问的资源将生成一个访问令牌(access token),用于后续的访问请求。 JWT(JSON Web Token)是一种用于在不同系统之间安全传输信息的标准。它是由三部分组成的字符串,包括头部(header)、载荷(payload)和签名(signature)。其中,载荷部分包含一些声明性的信息,用于标识用户或其他相关信息。签名部分则用于验证令牌的真实性和完整性。 单点登录(Single Sign-On,简称SSO)是一种身份验证机制,在一次登录后,允许用户访问多个相关系统,而无需重新进行身份验证。当用户进行初始身份验证后,一个包含JWT的令牌将生成并返回给用户。 想要获得JWT,用户需要先通过OAuth 2.0进行身份验证和授权。用户在第三方应用程序上进行登录,该应用程序将向授权服务器发送身份验证请求。授权服务器将验证用户的身份并颁发访问令牌。然后,用户将该令牌发送到资源服务器上进行鉴权。资源服务器将验证令牌的有效性,并使用私钥对JWT进行签名,保证其真实性。最后,资源服务器会返回给用户一个含有JWT的响应。 用户在后续的访问请求中,只需携带JWT即可进行授权,无需再次进行身份验证。资源服务器接收到带有JWT的请求后,将对其进行验证,并根据令牌中的声明信息进行相应的授权操作。 通过OAuth 2.0和JWT单点登录实现了用户在多个应用程序之间的无缝访问,提供了便捷的用户体验和更高的安全性。 ### 回答2: OAuth 2.0是一种用于授权的开放标准,用于允许用户提供给第三方应用程序已授权访问特定资源的权限。它使用Access Token来表示用户的授权凭证。 要获得JWT(JSON Web Token),首先需要进行OAuth 2.0的认证和授权流程。以下是一般的流程: 1. 用户访问应用程序,并选择使用单点登录进行身份验证。 2. 应用程序将用户重定向到认证服务器,以获取授权。 3. 用户在认证服务器上登录,并确认授权访问应用程序所需的资源。 4. 认证服务器将授权码(Authorization Code)传递给应用程序的回调URL。 5. 应用程序使用授权码向认证服务器请求访问令牌(Access Token)。 6. 认证服务器验证应用程序的身份,并向应用程序颁发访问令牌。 7. 应用程序将访问令牌保存在安全的位置,以供将来的API调用使用。 8. 应用程序使用访问令牌向API服务器请求受保护资源。 9. API服务器对访问令牌进行验证,并返回请求的资源。 10. 如果访问令牌有效,则应用程序可以将其作为JWT进行使用。 获得JWT的过程实际上是通过OAuth 2.0的授权流程获得访问令牌,然后将访问令牌转换为JWT格式。JWT是一种用JSON表示的安全令牌,它包含有关用户身份、权限和其他相关信息的声明。 在将访问令牌转换为JWT时,应用程序需要使用加密算法(如HMAC或RSA)对访问令牌进行签名,以确保令牌的完整性和安全性。 总之,要获得JWT,首先需要进行OAuth 2.0的认证和授权流程,获取访问令牌,然后将访问令牌转换为JWT格式。JWT可以用于实现单点登录和安全访问控制。 ### 回答3: OAuth 2.0和JWT是用于实现单点登录的两种常见的身份验证和授权机制。下面是关于如何获得JWT的简要解释。 在OAuth 2.0流程中,客户端首先将用户重定向到认证服务器以进行身份验证。用户成功登录后,认证服务器将授权码返回给客户端。接下来,客户端使用该授权码请求访问令牌,同时提供其客户端凭据。认证服务器根据验证客户端凭据,并验证授权码的有效性后,颁发一个访问令牌给客户端。访问令牌可以用于访问受保护的资源服务器。然而,JWT并不是OAuth 2.0规范的一部分,它是作为一种安全令牌的表示形式,可以用于在认证(Authentication)和授权(Authorization)之间传输和存储信息。 在实现单点登录中,当用户通过身份验证获得访问令牌后,应用程序使用该令牌向身份提供者(例如认证服务器)请求JWT令牌。身份提供者使用该访问令牌生成一个JWT令牌,并将其返回给应用程序作为响应。这个JWT令牌包含有关用户身份的信息。应用程序可以将该令牌存储在客户端的会话中,以便在其他资源服务器上验证用户身份时使用。 获得JWT的过程需要通过OAuth 2.0进行授权并使用访问令牌来请求JWT令牌。要么应用程序直接与身份提供者交互来获取JWT,要么使用一些第三方库或框架来实现该过程。无论是直接与身份提供者交互还是使用第三方库,都需要遵循OAuth 2.0和JWT的相应规范和流程,以确保安全性和正确性。 总之,获得JWT的过程包括通过OAuth 2.0获得访问令牌,并用该令牌向身份提供者请求生成JWT令牌。这个JWT令牌可以用于实现单点登录,并在其他资源服务器上验证用户身份。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值