畅购商城:Spring Security Oauth2 JWT(上)

畅购商城文章系列

畅购商城:分布式文件系统FastDFS
畅购商城:商品的SPU和SKU概念
畅购商城:Lua、OpenResty、Canal实现广告缓存
畅购商城:微服务网关和JWT令牌(上)
畅购商城:微服务网关和JWT令牌(下)
畅购商城:Spring Security Oauth2 JWT(上)
畅购商城:Spring Security Oauth2 JWT(下)
畅购商城:购物车
畅购商城:订单
畅购商城:微信支付


学习目标

  • 用户认证分析
  • 认证技术方案了解(单点登录+第三方授权认证)
  • SpringSecurity Oauth2.0入门
  • oauth2.0认证模式
    • 授权码授权模式
    • 密码授权模式
  • 授权流程
  • 用户授权认证开发

前言

资源服务授权和认证开发放在 畅购商城:Spring Security Oauth2 JWT(下)中讲。

1. 用户认证分析

在这里插入图片描述
上面流程图描述了用户要操作的各个微服务,用户查看个人信息需要访问客户微服务,下单需要访问订单微服务,秒杀抢购商品需要访问秒杀微服务。每个服务都需要认证用户的身份,身份认证成功后,需要识别用户的角色然后授权访问对应的功能。

1.1 认证与授权

身份认证

用户身份认证即用户去访问系统资源时系统要求验证用户的身份信息,身份合法方可继续访问。常见的用户身份认证表现形式有:用户名密码登录,指纹打卡等方式。说通俗点,就相当于校验用户账号密码是否正确。

用户授权

用户认证通过后去访问系统的资源,系统会判断用户是否拥有访问资源的权限,只允许访问有权限的系统资源,没有权限的资源将无法访问,这个过程叫用户授权。

1.2 单点登录

在这里插入图片描述
用户访问的项目中,至少有3个微服务需要识别用户身份,如果用户访问每个微服务都登录一次就太麻烦了,为了提高用户的体验,我们需要实现让用户在一个系统中登录,其他任意受信任的系统都可以访问,这个功能就叫单点登录。

单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。 SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统 。

1.3 第三方账号登录

1.3.1 第三方登录介绍

随着国内及国外巨头们的平台开放战略以及移动互联网的发展,第三方登录已经不是一个陌生的产品设计概念了。 所谓的第三方登录,是说基于用户在第三方平台上已有的账号和密码来快速完成己方应用的登录或者注册的功能。而这里的第三方平台,一般是已经拥有大量用户的平台,国外的比如Facebook,Twitter等,国内的比如微博、微信、QQ等。

1.3.2 第三方登录优点

  1. 相比于本地注册,第三方登录一般来说比较方便、快捷,能够显著降低用户的注册和登录成本,方便用户实现快捷登录或注册。
  2. 不用费尽心思地应付本地注册对账户名和密码的各种限制,如果不考虑昵称的重复性要求,几乎可以直接一个账号走遍天下,再也不用在大脑或者什么地方记住N多不同的网站或App的账号和密码,整个世界一下子清静了。
  3. 在第一次绑定成功之后,之后用户便可以实现一键登录,使得后续的登录操作比起应用内的登录来容易了很多。
  4. 对于某些喜欢社交,并希望将更多自己的生活内容展示给朋友的人来说,第三方登录可以实现把用户在应用内的活动同步到第三方平台上,省去了用户手动发布动态的麻烦。但对于某些比较注重个人隐私的用户来说,则会有一些担忧,所以龙哥所说的这个优点是有前提的。
  5. 因为降低了用户的注册或登录成本,从而减少由于本地注册的繁琐性而带来的隐形用户流失,最终提高注册转化率。
  6. 对于某些应用来说,使用第三方登录完全可以满足自己的需要,因此不必要设计和开发一套自己的账户体系。
  7. 通过授权,可以通过在第三方平台上分享用户在应用内的活动在第三方平台上宣传自己,从而增加产品知名度。
  8. 通过授权,可以获得该用户在第三方平台上的好友或粉丝等社交信息,从而后续可以针对用户的社交关系网进行有目的性的营销宣传,为产品的市场推广提供另一种渠道。

1.3.3 第三方认证

当需要访问第三方系统的资源时需要首先通过第三方系统的认证(例如:微信认证),由第三方系统对用户认证通过,并授权资源的访问权限。

在这里插入图片描述

2. 认证技术方案

2.1 单点登录技术方案

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

单点登录的特点是:

  1. 认证系统为独立的系统。
  2. 各子系统通过Http或其它协议与认证系统通信,完成用户认证。
  3. 用户身份信息存储在Redis集群。

Java中有很多用户认证的框架都可以实现单点登录:

  1. Apache Shiro.
  2. CAS
  3. Spring security CAS

2.2 Oauth2认证

【总结】:
OAuth2.0 属于一个开放的授权认证标准,允许用户授权第三方移动应用(例如:某官网)上来访问自己(例如:微信信息)服务器上的资源,用户无需向第三方提供账号和密码。

OAuth(开放授权)是一个开放标准,允许用户授权第三方移动应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容,OAuth2.0是OAuth协议的延续版本。

2.2.1 Oauth2认证流程

第三方认证技术方案最主要是解决认证协议的通用标准问题,因为要实现跨系统认证,各系统之间要遵循一定的接口协议。

OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。同时,任何第三方都可以使用OAUTH认证服务,任何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP、JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间,因而OAUTH是简易的。互联网很多服务如Open API,很多大公司如Google,Yahoo,Microsoft等都提供了OAUTH认证服务,这些都足以说明OAUTH标准逐渐成为开放资源授权的标准。

Oauth协议目前发展到2.0版本,1.0版本过于复杂,2.0版本已得到广泛应用。
参考:https://baike.baidu.com/item/oAuth/7153134?fr=aladdin
Oauth协议:https://tools.ietf.org/html/rfc6749

下边分析一个Oauth2.0认证的例子,黑马程序员网站使用微信认证(授权码授权)的过程:

在这里插入图片描述
上图流程分析:
①访问登录页面
②请求认证
③授权页面
④用户授权,腾讯服务器创建授权码,授权码就是一个随机字符
⑤将授权码给黑马官网
⑥用授权码申请令牌,腾讯服务器生成令牌->加密字符
⑦返回令牌
⑧获取用户信息,腾讯服务器校验令牌合法性
⑨若有效,则响应用户信息,显示用户信息

  1. 客户端请求第三方授权

用户进入黑马程序的登录页面,点击微信的图标以微信账号登录系统,用户是自己在微信里信息的资源拥有者。

点击“用QQ账号登录”出现一个二维码,此时用户扫描二维码,开始给黑马程序员授权。

  1. 资源拥有者同意给客户端授权

资源拥有者扫描二维码表示资源拥有者同意给客户端授权,微信会对资源拥有者的身份进行验证,
验证通过后,QQ会询问用户是否给授权黑马程序员访问自己的QQ数据,用户点击“确认登录”表示同意授权,QQ认证服务器会颁发一个授权码,并重定向到黑马程序员的网站。

  1. 客户端获取到授权码

请求认证服务器申请令牌,此过程用户看不到,客户端应用程序请求认证服务器,请求携带授权码。

  1. 认证服务器向客户端响应令牌

认证服务器验证了客户端请求的授权码,如果合法则给客户端颁发令牌,令牌是客户端访问资源的通行证。
此交互过程用户看不到,当客户端拿到令牌后,用户在黑马程序员看到已经登录成功。

  1. 客户端请求资源服务器的资源

客户端携带令牌访问资源服务器的资源。 黑马程序员网站携带令牌请求访问微信服务器获取用户的基本信息。

  1. 资源服务器返回受保护资源

资源服务器校验令牌的合法性,如果合法则向用户响应资源信息内容。

注意:资源服务器和认证服务器可以是一个服务也可以分开的服务,如果是分开的服务资源服务器通常要请求认证 服务器来校验令牌的合法性。

Oauth2.0认证流程如下: 引自Oauth2.0协议rfc6749 https://tools.ietf.org/html/rfc6749

在这里插入图片描述
在这里插入图片描述

  1. 客户端

本身不存储资源,需要通过资源拥有者的授权去请求资源服务器的资源,比如:畅购在线Android客户端、畅购在
线Web客户端(浏览器端)、微信客户端等。

  1. 资源拥有者

通常为用户,也可以是应用程序,即该资源的拥有者。

  1. 授权服务器(也称认证服务器)

用来对资源拥有的身份进行认证、对访问资源进行授权。客户端要想访问资源需要通过认证服务器由资源拥有者授 权后方可访问。

  1. 资源服务器

存储资源的服务器,比如,畅购网用户管理服务器存储了畅购网的用户信息等。客户端最终访问资源服务器获取资源信息。

2.2.2 Oauth2在项目的应用

Oauth2是一个标准的开放的授权协议,应用程序可以根据自己的要求去使用Oauth2,本项目使用Oauth2实现如 下目标:

1、畅购访问第三方系统的资源

畅购项目中->微信账号->登录

2、外部系统访问畅购的资源

3、畅购前端(客户端) 访问畅购微服务的资源。

4、畅购微服务之间访问资源,例如:微服务A访问微服务B的资源,B访问A的资源。

2.3 Spring security Oauth2认证解决方案

本项目采用 Spring security + Oauth2完成用户认证及用户授权,Spring security 是一个强大的和高度可定制的身份验证和访问控制框架,Spring security 框架集成了Oauth2协议,下图是项目认证架构图:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

流程:
前提首先单独搭建一个认证服务器,用来做用户登录和授权;

  1. 用户请求认证服务完成认证(登录)。

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

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

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

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

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

3. Security Oauth2.0入门

3.1 学习知识点说明

本项目认证服务基于Spring Security Oauth2进行构建,并在其基础上作了一些扩展,采用JWT令牌机制,并自定 义了用户身份信息的内容。 本教程的主要目标是学习在项目中集成Spring Security Oauth2的方法和流程,通过 spring Security Oauth2的研究需要达到以下目标:

1、理解Oauth2的授权码认证流程及密码认证的流程。

2、理解spring Security Oauth2的工作流程。

3、掌握资源服务集成spring Security框架完成Oauth2认证的流程。

3.2 搭建认证服务器

3.2.1 导入认证工程

3.2.2 application.yml配置

在这里插入图片描述

3.2.3 启动授权认证服务

启动之前,记得先启动eureka,再启动该授权认证工程。

3.3 Oauth2授权模式

3.3.1 Oauth2授权模式

Oauth2有以下授权模式:

1.授权码模式(Authorization Code)【常用】
2.隐式授权模式(Implicit) 【不常用】
3.密码模式(Resource Owner Password Credentials) 【常用】
4.客户端模式(Client Credentials)【不常用】

其中授权码模式和密码模式应用较多,本小节介绍授权码模式。

3.3.2 授权码授权实现

上边例举的程序员网站使用QQ认证的过程就是授权码模式,流程如下:

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参数(授权码)

首先跳转到登录页面,输入客户端ID和客户端秘钥,点击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。

(3)令牌校验

Spring Security Oauth2提供校验令牌的端点,如下:

Get: http://localhost:9001/oauth/check_token?token= [access_token]

(4)刷新令牌

刷新令牌是当令牌快过期时重新生成一个令牌,它于授权码授权和密码授权生成令牌不同,刷新令牌不需要授权码 也不需要账号和密码,只需要一个刷新令牌、客户端id和客户端密码。

3.3.3 密码授权实现

(1)认证

密码模式(Resource Owner Password Credentials)与授权码模式的区别是申请令牌不再使用授权码,而是直接通过用户名和密码即可申请令牌

测试:

Post请求:http://localhost:9001/oauth/token

参数:

grant_type:密码模式授权填写password

username:账号 -用户账号

password:密码 -用户密码

即便用密码授权,客户端ID和客户端秘钥也必须要传到后台认证。

并且此链接需要使用 http Basic认证。

(2)校验令牌

Spring Security Oauth2提供校验令牌的端点,如下:

Get: http://localhost:9001/oauth/check_token?token=

参数:

token:令牌

(3)刷新令牌

刷新令牌是当令牌快过期时重新生成一个令牌,它于授权码授权和密码授权生成令牌不同,刷新令牌不需要授权码 也不需要账号和密码,只需要一个刷新令牌、客户端id和客户端密码。

测试: Post:http://localhost:9001/oauth/token

参数:

grant_type: 固定为 refresh_token

refresh_token:刷新令牌(注意不是access_token,而是refresh_token)

3.3.4 Oauth2.0总结

授权模式4种:

1.授权码模式(Authorization Code)【常用】
2.隐式授权模式(Implicit) 【不常用】
3.密码模式(Resource Owner Password Credentials) 【常用】
4.客户端模式(Client Credentials)【不常用】

授权码模式授权:

  1. 申请授权码 http://localhost:9001/oauth/authorize?client_id=changgou&response_type=code&scop=app&redirect_uri=http://localhost
  2. 登录界面输入客户端ID和客户端秘钥
  3. 点击 authorize 授权获取授权码
  4. 用户授权码获取令牌 http://localhost:9001/oauth/token

密码模式授权:

  1. 客户端ID和客户端秘钥需要传递到后台
  2. 用户账号和密码

总结

本文主要讲述用户认证分析,认证技术方案以及Security Oauth2.0入门,资源服务授权和认证开发放在 畅购商城:Spring Security Oauth2 JWT(下)中讲。

猜你喜欢

转载自blog.csdn.net/weixin_42871468/article/details/114081453