目录
- 一.认证分析
- 1.1 单点登录
- 1.2 第三方账户登录
- 1.2.1 第三方账户登录介绍
- 1.2.2第三方登录优点
- 1.3.1 第三方认证
- 二.认证技术方案
- 2.1 单点登录技术方案
- 2.2 Oauth2认证
- 2.2.1 Oauth2在项目中的应用
- 2.2.2 Spring Security Oauth2认证解决方案
- 三 Security Oauth2.0入门
- 3.1Oauth2授权模式
- 3.3.2 授权码授权实现
- 3.3.3 密码授权实现
一.认证分析
1.1 单点登录
当用户访问的项目中,至少有三个微服务需要识别用户身份,如果用户访问每个微服务都需要登录一次的话,非常繁琐,为了提高用户的体验,我们需要实现让用户在一个系统中登录,其他受信任的系统都可以访问,这个功能就叫做单点登录。
单点登录(Single Sign On),简称为SSO,是目前比较流行的企业业务整合的解决方案之一,SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统
1.2 第三方账户登录
1.2.1 第三方账户登录介绍
随着国内及国外巨头们的平台开放战略以及移动互联网的发展,第三方登录已经不是一个陌生的产品设计概念了。 所谓的第三方登录,是说基于用户在第三方平台上已有的账号和密码来快速完成己方应用的登录或者注册的功能。而这里的第三方平台,一般是已经拥有大量用户的平台,国外的比如Facebook,Twitter等,国内的比如微博、微信、QQ等。
1.2.2第三方登录优点
1.相比于本地注册,第三方登录一般来说比较方便,快捷,能够显著降低用户的注册和登录成本,方便用户实现快捷登录或者注册
2.不用费尽心思地应付本地注册对账户名和密码的各种限制,如果不考虑昵称的重复性要求,几乎可以直接一个账号走遍天下,再也不用在大脑或者什么地方记住N多不同的网站或App的账号和密码,整个世界一下子清静了。
3.在第一次绑定成功之后,之后用户便可以实现一键登录,使得后续的登录操作比起应用内的登录来容易了很多。
4.对于某些喜欢社交,并希望将更多自己的生活内容展示给朋友的人来说,第三方登录可以实现把用户在应用内的活动同步到第三方平台上,省去了用户手动发布动态的麻烦。但对于某些比较注重个人隐私的用户来说,则会有一些担忧,所以龙哥所说的这个优点是有前提的。
5.因为降低了用户的注册或登录成本,从而减少由于本地注册的繁琐性而带来的隐形用户流失,最终提高注册转化率。
6.对于某些应用来说,使用第三方登录完全可以满足自己的需要,因此不必要设计和开发一套自己的账户体系。
7.通过授权,可以通过在第三方平台上分享用户在应用内的活动在第三方平台上宣传自己,从而增加产品知名度。
8.通过授权,可以获得该用户在第三方平台上的好友或粉丝等社交信息,从而后续可以针对用户的社交关系网进行有目的性的营销宣传,为产品的市场推广提供另一种渠道。
1.3.1 第三方认证
当需要访问第三方系统的资源时需要首先通过第三方系统的认证(例如:微信认证),由第三方系统对用户认证通过,并授权资源的访问权限
二.认证技术方案
2.1 单点登录技术方案
分布式系统要实现单点登录,通常将认证系统独立抽取出来,并且将用户省份信息存储在单独的存储介质,比如:Mysql、redi、考虑性能的要求,通常存储在Redis中。
单点登录的特点是
1.认证系统为独立的系统
2.各子系统通过HTTP或其他协议与认证系统通信,完成用户认证
3.用户身份信息存储在Redis集群
2.2 Oauth2认证
OAuth(开放授权)是一个开放标准,允许用户授权第三方移动应用来访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用来分享他们数据的所有内容,OAuth2.0是OAuth协议的延续版本。
例如 :微信扫描登录
Oauth2包括以下角色
- 客户端 :本身不存储资源,需要通过资源拥有者的授权去请求资源服务器的资源,比如:微信在线客户端、畅购在线Web客户端(浏览器端)
- 资源拥有者:通常为用户,也可以是应用程序,即该资源的拥有者
- 授权服务器(认证服务器):用来对资源拥有的身份进行认证、对访问资源进行授权。客户端要想访问资源需要通过认证服务器由资源拥有着授权后可访问
- 资源服务器:存储资源的服务器,客户端最终访问资源服务器来获取资源信息
2.2.1 Oauth2在项目中的应用
【访问畅购商城网站】
- 畅购访问第三方系统的资源
- 外部系统访问畅购的资源
- 畅购前端(客户端)访问畅购微服务的资源
- 畅购微服务之间访问资源,例如:微服务A访问微服务B的资源,B访问A的资源
2.2.2 Spring Security Oauth2认证解决方案
- 用户请求认证服务完成认证(认证流程为)。
- 认证服务下发用户身份令牌,拥有身份令牌表示身份合法。
- 用户携带令牌请求资源服务,请求资源服务先经过网关。
- 网关校验用户身份令牌的合法,不合法表示用户没有登陆,如果合法则放行继续访问。
- 资源服务获取令牌,根据令牌完成授权。
- 资源服务完成授权则响应资源信息。
三 Security Oauth2.0入门
注意:
1.以下操作必须导入Oauth2.0认证完整代码,可在百度中自己查找
2.下载postman软件,可在官网下载
3.下面演示了具体的流程直接看图片显示效果理解
3.1Oauth2授权模式
Oauth2有以下授权模式:
1.授权码模式(Authorization Code)【常用】
2.隐式授权模式(Implicit)
3.密码模式(Resource Owner Password Credentials) 【常用】
4.客户端模式(Client Credentials)
3.3.2 授权码授权实现
1、客户端请求第三方授权
2、用户(资源拥有者)同意给客户端授权
3、客户端获取到授权码,请求认证服务器申请 令牌
4、认证服务器向客户端响应令牌
5、客户端请求资源服务器的资源,资源服务校验令牌合法性,完成授权
6、资源服务器返回受保护资源
(1)申请授权码
请求认证服务获取授权码:
Get请求:
http://localhost:9001/oauth/authorize?client_id=changgou&response_type=code&scop=app&redirect_uri=http://localhost
参数列表如下:
client_id:客户端id,和授权配置类中设置的客户端id一致。
response_type:授权码模式固定为code
scop:客户端范围,和授权配置类中设置的scop一致。
redirect_uri:跳转uri,当授权码申请成功后会跳转到此地址,并在后边带上code参数(授权码)
首先跳转到登录页面:
输入账号和密码,点击Login。 Spring Security接收到请求会调用UserDetailsService接口的loadUserByUsername方法查询用户正确的密码。 当前导入的基础工程中客户端ID为changgou,秘钥也为changgou即可认证通过。
接下来进入授权页面:
点击Authorize,接下来返回授权码: 认证服务携带授权码跳转redirect_uri,code=k45iLY就是返回的授权码
(2)申请令牌
拿到授权码后,申请令牌。 Post请求:http://localhost:9001/oauth/token 参数如下:
grant_type:授权类型,填写authorization_code,表示授权码模式
code:授权码,就是刚刚获取的授权码,注意:授权码只使用一次就无效了,需要重新申请。
redirect_uri:申请授权码时的跳转url,一定和申请授权码时用的redirect_uri一致。
此链接需要使用 http Basic认证。 什么是http Basic认证? http协议定义的一种认证方式,将客户端id和客户端密码按照“客户端ID:客户端密码”的格式拼接,并用base64编 码,放在header中请求服务端,一个例子: Authorization:Basic WGNXZWJBcHA6WGNXZWJBcHA=WGNXZWJBcHA6WGNXZWJBcHA= 是用户名:密码的base64编码。 认证失败服务端返回 401 Unauthorized。
以上测试使用postman完成:
http basic认证:
客户端Id和客户端密码会匹配数据库oauth_client_details表中的客户端id及客户端密码。点击发送: 申请令牌成功
返回信如下:
access_token:访问令牌,携带此令牌访问资源
token_type:有MAC Token与Bearer Token两种类型,两种的校验算法不同,RFC 6750建议Oauth2采用 Bearer Token(http://www.rfcreader.com/#rfc6750)。
refresh_token:刷新令牌,使用此令牌可以延长访问令牌的过期时间。
expires_in:过期时间,单位为秒。
scope:范围,与定义的客户端范围一致。
jti:当前token的唯一标识
(3)令牌校验
Spring Security Oauth2提供校验令牌的端点,如下:
Get: http://localhost:9001/oauth/check_token?token= [access_token]
参数:
token:令牌
使用postman测试如下:
如果令牌校验失败,会出现如下结果:
如果令牌过期了,会如下如下结果:
(4)刷新令牌
刷新令牌是当令牌快过期时重新生成一个令牌,它于授权码授权和密码授权生成令牌不同,刷新令牌不需要授权码 也不需要账号和密码,只需要一个刷新令牌、客户端id和客户端密码。
测试如下: Post:http://localhost:9001/oauth/token
参数:
grant_type: 固定为 refresh_token
refresh_token:刷新令牌(注意不是access_token,而是refresh_token)
3.3.3 密码授权实现
(1)认证
密码模式(Resource Owner Password Credentials)与授权码模式的区别是申请令牌不再使用授权码,而是直接 通过用户名和密码即可申请令牌。
测试如下:
Post请求:http://localhost:9001/oauth/token
参数:
grant_type:密码模式授权填写password
username:账号
password:密码
并且此链接需要使用 http Basic认证。
测试数据如下:
(2)校验令牌
Spring Security Oauth2提供校验令牌的端点,如下:
Get: http://localhost:9001/oauth/check_token?token=
参数:
token:令牌
使用postman测试如下:
返回结果:
{
"companyId": null,
"userpic": null,
"scope": [
"app"
],
"name": null,
"utype": null,
"active": true,
"id": null,
"exp": 1990221534,
"jti": "5b96666e-436b-4301-91b5-d89f9bbe6edb",
"client_id": "changgou",
"username": "szitheima"
}
exp:过期时间,long类型,距离1970年的秒数(new Date().getTime()可得到当前时间距离1970年的毫秒数)。
user_name: 用户名
client_id:客户端Id,在oauth_client_details中配置
scope:客户端范围,在oauth_client_details表中配置
jti:与令牌对应的唯一标识 companyId、userpic、name、utype、
id:这些字段是本认证服务在Spring Security基础上扩展的用户身份信息
(3)刷新令牌
刷新令牌是当令牌快过期时重新生成一个令牌,它于授权码授权和密码授权生成令牌不同,刷新令牌不需要授权码 也不需要账号和密码,只需要一个刷新令牌、客户端id和客户端密码。
测试如下: Post:http://localhost:9001/oauth/token
参数:
grant_type: 固定为 refresh_token
refresh_token:刷新令牌(注意不是access_token,而是refresh_token)
刷新令牌成功,会重新生成新的访问令牌和刷新令牌,令牌的有效期也比旧令牌长。
刷新令牌通常是在令牌快过期时进行刷新 。