单点登录(SSO)-- 实现单点登录的几种方式

1.为什么需要单点登录

三个角度:
1.1 方便用户的使用:用户登录一次,可以使用不同的服务和页面,省了忘记密码的痛苦

1.2 简化开发:'SSO'让开发人员只要开发一个通用的身份验证框架,就不用为身份验证操心了

1.3 方便管理:
如果应用程序加入了单点登录协议,管理用户帐号的负担就会减轻。简化的程度取决于应用程序,因为
SSO 只处理身份验证。所以,应用程序可能仍然需要设置用户的属性(比如访问特权)。

2.单点登陆的来源

2.1早期的单机部署:web单系统应用

早期开发web应用都是所有的包放在一起打成一个war包放入tomcat容器来运行的。
所有的功能和业务:后台管理,门户界面的等,	都是由这一个war来支持的。
这样的单应用,也称之为巨石应用,因为十分不好扩展和拆分。

在巨石应用下,用户的登录以及权限就显得十分简单。用户登录成功后,把相关信息放入会话中。
HTTP维护这个会话,再每次用户请求服务器的时候来验证这个会话即可,大致可以用下图来表示:

在这里插入图片描述

验证登录的这个会话就是session,维护了用户状态,也就是所谓的HTTP有状态协议,
我们经常可以在浏览器中看到JSESSIONID,这个就是用来维持这个关系的key。
2.2分布式集群部署:
由于网站的访问量越来也大,单机部署已经是巨大瓶颈,所以才有了后来的分布式集群部署。

例如:如果引入集群的概念,1单应用可能重新部署在3台tomcat以上服务器,使用nginx来实现反向代理。
此时,这个session就无法在这3台tomcat上共享,用户信息会丢失,所以不得不考虑多服务器之间的session同步问
题,这就是单点登陆的来源。

在这里插入图片描述

3、单点登陆的实现方式

加粗样式

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

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

**2.分布式session方式实现单点登录**
例如阿里有很多系统分割为多个子系统,独立部署后,不可避免的会遇到会话管理的问题,
类似这样的电商网站一般采用分布式Session实现。进一步可以根据分布式Session,建立完善的单点登录或账户管理系统。

流程运行:
(1) 用户第一次登录时,将会话信息(用户Id和用户信息),比如以用户IdKey,写入分布式Session;
(2) 用户再次登录时,获取分布式Session,是否有会话信息,如果没有则调到登录页;
(3) 一般采用Cache中间件实现,建议使用Redis,因此它有持久化功能,方便分布式Session宕机后,可以从持久化存储中加载会话信息;
(4) 存入会话时,可以设置会话保持的时间,比如15分钟,超过后自动超时;

结合Cache中间件,实现的分布式Session,可以很好的模拟Session会话。

在这里插入图片描述

4. 单点登录技术方案(Spring security Oauth2)

分布式系统要实现单点登录,通常将认证系统独立抽取出来,并且将用户身份信息存储在单独的存储介质,比如: MySQL、Redis,考虑性能要求,通常存储在Redis中,如下图:
在这里插入图片描述
Java中有很多用户认证的框架都可以实现单点登录:

 1Apache Shiro. 
 2、CAS 
 3Spring security   

4.1 Spring security Oauth2认证解决方案

Spring security 是一个强大的和高度可定制的身份验证和访问控制框架,集成了Oauth2协议>
下图是项目认证架构图:

在这里插入图片描述

1、用户请求认证服务完成认证。

2、认证服务下发用户身份令牌,拥有身份令牌表示身份合法。

3、用户携带令牌请求资源服务,请求资源服务必先经过网关。

4、网关校验用户身份令牌的合法,不合法表示用户没有登录,如果合法则放行继续访问。

5、资源服务获取令牌,根据令牌完成授权。

6、资源服务完成授权则响应资源信息。

在这里插入图片描述
实际认证功能流程图如下
在这里插入图片描述
执行流程:

1、用户登录,请求认证服务 
2、认证服务认证通过,生成jwt令牌,将jwt令牌及相关信息写入Redis,并且将身份令牌写入cookie()
3、用户访问资源页面,带着cookie到网关 
4、网关从cookie获取token,并查询Redis校验token,如果token不存在则拒绝访问,否则放行 
5、用户退出,请求认证服务,清除redis中的token,并且删除cookie中的token 

使用redis存储用户的身份令牌有以下作用:

1、实现用户退出注销功能,服务端清除令牌后,即使客户端请求携带token也是无效的。 
2、由于jwt令牌过长,不宜存储在cookie中,所以将jwt令牌存储在redis,由客户端请求服务端获取并在客户端存储。

认证服务需要实现的功能如下:

1、登录接口
前端post提交账号、密码等,用户身份校验通过,生成令牌,并将令牌存储到redis。 将令牌写入cookie。

2、退出接口 校验当前用户的身份为合法并且为已登录状态。 将令牌从redis删除。 删除cookie中的令牌

在这里插入图片描述

4.2 Jwt令牌

JSON Web Token(JWT)是一个开放的行业标准(RFC 7519)
它定义了一种简介的、自包含的协议格式,用于在通信双方传递json对象,传递的信息经过数字签名可以被验证和信任。
JWT可以使用HMAC算法或使用RSA的公 钥/私钥对来签名,防止被篡改。

官网:https://jwt.io/
标准:https://tools.ietf.org/html/rfc7519

JWT令牌的优点:
1、jwt基于json,非常方便解析。 
2、可以在令牌中自定义丰富的内容,易扩展。 
3、通过非对称加密算法及数字签名技术,JWT防止篡改,安全性高。 
4、资源服务使用JWT可不依赖认证服务即可完成授权。

缺点:
1、JWT令牌较长,占存储空间比较大。    

4.21令牌结构

JWT令牌由三部分组成,每部分中间使用点(.)分隔,比如:xxxxx.yyyyy.zzz
1.Header:
头部包括令牌的类型(即JWT)及使用的哈希算法(如HMAC SHA256或RSA)
一个例子如下:
下边是Header部分的内容
{
    "alg": "HS256",
    "typ": "JWT"
}
将上边的内容使用Base64Url编码,得到一个字符串就是JWT令牌的第一部分.
Payload:
第二部分是负载,内容也是一个json对象,它是存放有效信息的地方,它可以存放jwt提供的现成字段,比 如:iss(签发者),exp(过期时间戳), sub(面向的用户)等,也可自定义字段。

此部分不建议存放敏感信息,因为此部分可以解码还原原始内容。

最后将第二部分负载使用Base64Url编码,得到一个字符串就是JWT令牌的第二部分。

一个例子:
{
    "sub": "1234567890",
    "name": "456",
    "admin": true
}
Signature
第三部分是签名,此部分用于防止jwt内容被篡改。

这个部分使用base64url将前两部分进行编码,编码后使用点(.)连接组成字符串,最后使用header中声明 签名算法进行签名。

一个例子:
HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    secret)
base64UrlEncode(header):jwt令牌的第一部分。

base64UrlEncode(payload):jwt令牌的第二部分。

secret:签名所使用的密钥。

4.22 生成私钥公钥

JWT令牌生成采用非对称加密算法
1、生成密钥证书 下边命令生成密钥证书,采用RSA 算法每个证书包含公钥和私钥

keytool -genkeypair -alias changgou -keyalg RSA -keypass changgou -keystore changgou.jks -storepass changgou 

Keytool 是一个java提供的证书管理工具

-alias:密钥的别名 
-keyalg:使用的hash算法 
-keypass:密钥的访问密码 
-keystore:密钥库文件名,changgou.jks保存了生成的证书 
-storepass:密钥库的访问密码 

查询证书信息:

keytool -list -keystore changgou.jks

2、导出公钥
openssl是一个加解密工具包,这里使用openssl来导出公钥信息。

安装 openssl:http://slproweb.com/products/Win32OpenSSL.html
配置openssl的path环境变量,cmd进入changgou.jks文件所在目录执行如下命令:

keytool -list -rfc --keystore changgou.jks | openssl x509 -inform pem -pubkey

在这里插入图片描述
下面段内容是公钥

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvFsEiaLvij9C1Mz+oyAm
t47whAaRkRu/8kePM+X8760UGU0RMwGti6Z9y3LQ0RvK6I0brXmbGB/RsN38PVnh
cP8ZfxGUH26kX0RK+tlrxcrG+HkPYOH4XPAL8Q1lu1n9x3tLcIPxq8ZZtuIyKYEm
oLKyMsvTviG5flTpDprT25unWgE4md1kthRWXOnfWHATVY7Y/r4obiOL1mS5bEa/
iNKotQNnvIAKtjBM4RlIDWMa6dmz+lHtLtqDD2LF1qwoiSIHI75LQZ/CNYaHCfZS
xtOydpNKq8eb1/PGiLNolD4La2zf0/1dlcr5mkesV570NxRmU1tFm8Zd3MZlZmyv
9QIDAQAB
-----END PUBLIC KEY-----

将上边的公钥拷贝到文本public.key文件中,合并为一行,可以将它放到需要实现授权认证的工程中。

  • 8
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
单点登录(Single Sign-On,简称SSO)是一种身份认证和授权机制,允许用户使用一组凭据(如用户名和密码)登录到多个应用程序或系统中,而无需为每个应用程序单独进行认证。 SSO实现原理通常涉及以下几个主要组件: 1. 身份提供者(Identity Provider,简称IdP):身份提供者是负责用户身份验证和授权的中心服务。它维护用户的身份信息,并为用户生成令牌(Token)。 2. 服务提供者(Service Provider,简称SP):服务提供者是需要接受SSO认证的应用程序或系统。它依赖于身份提供者来验证用户身份,并根据用户的授权信息提供相应的服务。 3. 用户代理(User Agent):用户代理是指用户使用的浏览器或移动设备等客户端应用程序。用户代理在用户登录时与身份提供者进行交互,并在成功认证后将令牌发送给服务提供者。 下面是SSO的基本实现流程: 1. 用户访问服务提供者的应用程序,并尚未进行身份验证。 2. 服务提供者检测到用户未经身份验证,将用户重定向到身份提供者的登录页面。 3. 用户在身份提供者的登录页面上输入凭据(如用户名和密码)进行身份验证。 4. 身份提供者验证用户的凭据,并生成一个令牌,其中包含有关用户身份和授权的信息。 5. 身份提供者将令牌返回给用户代理。 6. 用户代理将令牌发送给服务提供者。 7. 服务提供者接收到令牌后,向身份提供者验证令牌的有效性和真实性。 8. 验证成功后,服务提供者将用户标识为已经通过身份验证,并为用户提供相应的服务。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

酆都小菜鬼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值