1.单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。 SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统
2.单点登录技术方案
分布式系统要实现单点登录,通常将认证系统独立抽取出来,并且将用户身份信息存储在单独的存储介质,比如: MySQL、Redis,考虑性能要求,通常存储在Redis中,如下图:
在访问服务之前都需要进行用户认证,认证通过,将用户信息存储到Redis,访问其它互相信任服务时便不需要再次登录,若Redis中没有信息或信息过期,则需重新登录;目前有很多用户认证的框架可以实现单点登录,如 Apache Shiro,CAS , Spring security等。
第三方登录技术第三方认证技术方案最主要是解决认证协议的通用标准问题,因为要实现跨系统认证,各系统之间要遵循一定的 接口协议。AUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。同时,任何第三方都可以使用OAUTH认 证服务,任何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。
业界提供了OAUTH的多种实现如PHP、Javascript,Java,Ruby等各种语言开发包,大大节约了程序员的时间,因而OAUTH是简易的。互联网很多服务如Open API,很多大公司如Google,Yahoo,Microsoft等都提供了OAUTH认证服务,这些都足以说明OAUTH标准逐渐成为开放资源授权的标准。 Oauth协议目前发展到2.0版本,1.0版本过于复杂,2.0版本已得到广泛应用。
Oauth2认证流程如下:
Oauth2认证中包括的角色:
客户端 :本身不存储资源,需要通过资源拥有者的授权去请求资源服务器的资源
资源拥有者 :通常为用户,也可以是应用程序,即该资源的拥有者
授权服务器(也称认证服务器): 用来对资源拥有的身份进行认证、对访问资源进行授权。客户端要想访问资源需要通过认证服务器由资源拥有者授 权后方可访问。
资源服务器 :存储资源的服务器,比如,畅购用户管理服务器存储了畅购的用户信息,微信的资源服务存储了微信的用户信息等。客户端最终访问资源服务器获取资源信息。
下面,举一个Oauth2认证的实例
1.客户端请求第三方授权
用户进入百度网盘的登录页面,点击QQ的图标以QQ账号登录系统,用户是自己在QQ里信息的资源拥有者。
点击“用QQ账号登录”出现一个二维码,此时用户扫描二维码,开始给百度网盘授权。(我这里电脑已经登录过QQ,所以可以点击头像授权)
2.资源拥有者同意给客户端授权
资源拥有者扫描二维码表示资源拥有者同意给客户端授权,QQ会对资源拥有者的身份进行验证, 验证通过后,QQ会询问用户是否给授权百度网盘访问自己的QQ数据,用户点击“确认登录”表示同意授权,QQ认证服务器会 颁发一个授权码,并重定向到百度网盘的网站。
3.客户端获取到授权码,请求认证服务器申请令牌 此过程用户看不到,客户端应用程序请求认证服务器,请求携带授权码。
4.认证服务器向客户端响应令牌 认证服务器验证了客户端请求的授权码,如果合法则给客户端颁发令牌,令牌是客户端访问资源的通行证。 此交互过程用户看不到,当客户端拿到令牌后,用户在百度网盘看到已经登录成功。
5.客户端请求资源服务器的资源 客户端携带令牌访问资源服务器的资源。 百度网盘网站携带令牌请求访问QQ服务器获取用户的基本信息。
6.资源服务器返回受保护资源 资源服务器校验令牌的合法性,如果合法则向用户响应资源信息内容。 注意:资源服务器和认证服务器可以是一个服务也可以分开的服务,如果是分开的服务资源服务器通常要请求认证 服务器来校验令牌的合法性。
Oauth2在项目的应用Oauth2是一个标准的开放的授权协议,应用程序可以根据自己的要求去使用Oauth2,项目中使用Oauth2可以实现实现如下功能:
1、本系统访问第三方系统的资源
2、外部系统访问本系统的资源
3、本系统前端(客户端) 访问本系统后端微服务的资源。
4、本系统微服务之间访问资源,例如:微服务A访问微服务B的资源,B访问A的资源。
Spring security Oauth2认证解决方案采用 Spring security + Oauth2+JWT完成用户认证及用户授权,Spring security 是一个强大的和高度可定制的身份验证和访问控制框架,Spring security 框架集成了Oauth2协议,下图是项目认证架构图:
1、用户请求认证服务完成认证。
2、认证服务下发用户身份令牌,拥有身份令牌表示身份合法。
3、用户携带令牌请求资源服务,请求资源服务必先经过网关。
4、网关校验用户身份令牌的合法,不合法表示用户没有登录,如果合法则放行继续访问。
5、资源服务获取令牌,根据令牌完成授权。
6、资源服务完成授权则响应资源信息。
(补充)Jwt令牌JSON Web Token(JWT)是一个开放的行业标准(RFC 7519),它定义了一种简介的、自包含的协议格式,用于 在通信双方传递json对象,传递的信息经过数字签名可以被验证和信任。JWT可以使用HMAC算法或使用RSA的公 钥/私钥对来签名,防止被篡改。
JWT令牌的优点
- jwt基于json,非常方便解析。
- 可以在令牌中自定义丰富的内容,易扩展。
- 通过非对称加密算法及数字签名技术,JWT防止篡改,安全性高。
- 资源服务使用JWT可不依赖认证服务即可完成授权。
缺点:JWT令牌较长,占存储空间比较大
令牌结构:JWT令牌由三部分组成,每部分中间使用点(.)分隔,比如:xxxxx.yyyyy.zzzzz
1、Header:头部包括令牌的类型(即JWT)及使用的哈希算法(如HMAC SHA256或RSA)例如:
{
"alg": "HS256", //使用的hash算法
"typ": "JWT" //令牌类型
}
将第一部分的内容使用base64Url编码,得到一个字符串就是JWT令牌的第一部分
2.Payload:负载,内容也是一个json对象,它是存放有效信息的地方,它可以存放jwt提供的现成字段,比 如:iss(签发者),exp(过期时间戳), sub(面向的用户)等,也可自定义字段。此部分不建议存放敏感信息,因为此部分可以解码还原原始内容。例如:
{
"sub": "1234567890",
"name": "456",
"admin": true
}
将第二部分负载使用base64Url编码,得到一个字符串就是JWT令牌的第二部分。
3.Signature:签名,此部分用于防止jwt内容被篡改。
这个部分使用base64url将前两部分进行编码,编码后使用点(.)连接组成字符串,最后使用header中声明 签名算法进行签名。例如:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
secret:签名所使用的密钥。
生成私钥公钥:JWT令牌生成采用非对称加密算法
1.生成秘钥证书:采用RSA 算法每个证书包含公钥和私钥
keytool -genkeypair -alias cmcm -keyalg RSA -keypass cmcm -keystore cmcm.jks -storepass cmcm
Keytool 是一个java提供的证书管理工具
-alias:密钥的别名 -keyalg:使用的hash算法 -keypass:密钥的访问密码 -keystore:密钥库文件名,密钥库文件名.jks保存了生成的证书 -storepass:密钥库的访问密码
查询证书信息:
keytool -list -keystore cmcm.jks
导出公钥
openssl是一个加解密工具包,这里使用openssl来导出公钥信息。
安装 openssl:Win32/Win64 OpenSSL Installer for Windows - Shining Light Productions
安装好后配置openssl的path环境变量
cmd进入 密钥库文件名.jks文件所在目录执行如下命令:
keytool -list -rfc --keystore cmcm.jks | openssl x509 -inform pem -pubkey
将上边的公钥拷贝到文本public.key文件中,合并为一行,可以将它放到需要实现授权认证的工程中。将公钥和cmcm.jks放入授权认证服务中的resources中,用于生成令牌
上面用Spring security实现单点登录,用jwt来生成公私钥,通过公私钥生成和校验令牌,接下来要实现的是Oauth2授权;
Oauth2授权模式
四种授权模式:
- 授权码模式(Authorization Code)
- 隐式授权模式(Implicit)
- 密码模式(Resource Owner Password Credentials)
- 客户端模式(Client Credentials)
其中授权码模式和密码模式应用较多
授权码模式授权
上边例举的百度网盘登录使用QQ认证的过程就是授权码模式,流程如下:
1、客户端请求第三方授权
2、用户同意给客户端授权
3、客户端获取到授权码,请求认证服务器申请 令牌
4、认证服务器向客户端响应令牌
5、客户端请求资源服务器的资源,资源服务校验令牌合法性,完成授权
6、资源服务器返回受保护资源
密码模式授权:密码模式(Resource Owner Password Credentials)与授权码模式的区别是申请令牌不再使用授权码,而是直接 通过用户名和密码即可申请令牌。这里在认证服务中还需要一个登录验证,账号和密码匹配正确,才能生成令牌
资源服务授权:
资源服务拥有要访问的受保护资源,客户端携带令牌访问资源服务,如果令牌合法则可成功访问资源服务中的资源,如下图:
流程:
1、客户端请求认证服务申请令牌 2、认证服务生成令牌认证服务采用非对称加密算法,使用私钥生成令牌。 3、客户端携带令牌访问资源服务客户端在Http header 中添加: Authorization:Bearer令牌。 4、资源服务请求认证服务校验令牌的有效性资源服务接收到令牌,使用公钥校验令牌的合法性 5、令牌有效,资源服务向客户端响应资源信息
受保护资源服务与Oauth2的对接
1.配置公钥:将公钥放到该服务资源文件夹下
2.添加oauth2依赖
org.springframework.cloud spring-cloud-starter-oauth2
3.增加配置类:(该配置类中配置每个系统的Http请求路径安全控制策略以及读取公钥信息识别令牌)
重启服务后,请求必须携带令牌,且令牌正确才能访问该服务资源
认证开发功能流程图如下:
整合后如下:



