作者:微信小助手
发布时间:2021-12-03T03:11:20
本篇文章介绍一下OAuth2.0相关的知识点,并且手把手带大家搭建一个认证授权中心、资源服务进行OAuth2.0四种授权模式的验证,案例源码详细,一梭子带大家了解清楚。 本篇文章的案例源码项目架构为:Spring Boot + Spring Cloud Alibaba + Spring Security 。 文章目录如下: 编码永远都是为了解决生产中的问题,想要理解为什么需要OAuth2,当然要从实际生活出发。 举个例子:小区的业主点了一份外卖,但是小区的门禁系统不给外卖人员进入,此时想要外卖员进入只能业主下来开门或者告知门禁的密码。 密码告知外卖员岂不是每次都能凭密码进入小区了,这明显造成了安全隐患。 那么有没有一种方案:既能不泄露密码,也能让外卖小哥进入呢? 于是此时就想到了一个授权机制,分为以下几个步骤: 另外这个授权的密码不仅可以通过门禁,还可以通过楼下的门禁,这就非常类似于网关和微服务了。 上述例子中令牌和密码的作用是一样的,都可以进入小区,但是存在以下几点差异: OAuth 是一个开放标准,该标准允许用户让第三方应用访问该用户在某一网站上存储的私密资源(如头像、照片、视频等),而在这个过程中无需将用户名和密码提供给第三方应用。实现这一功能是通过提供一个令牌(token),而不是用户名和密码来访问他们存放在特定服务提供者的数据。 采用令牌(token)的方式可以让用户灵活的对第三方应用授权或者收回权限。 OAuth2 是 OAuth 协议的下一版本,但不向下兼容 OAuth 1.0。 传统的 Web 开发登录认证一般都是基于 session 的,但是在前后端分离的架构中继续使用 session 就会有许多不便,因为移动端(Android、iOS、微信小程序等)要么不支持 cookie(微信小程序),要么使用非常不便,对于这些问题,使用 OAuth2 认证都能解决。 对于大家而言,我们在互联网应用中最常见的 OAuth2 应该就是各种第三方登录了,例如 QQ 授权登录、微信授权登录、微博授权登录、GitHub 授权登录等等。 OAuth2.0协议一共支持 4 种不同的授权模式: 这种方式是最常用的流程,安全性也最高,它适用于那些有后端的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。 令牌获取的流程如下: 上图中涉及到两个角色,分别是客户端、认证中心,客户端负责拿令牌,认证中心负责发放令牌。 但是不是所有客户端都有权限请求令牌的,需要事先在认证中心申请,比如微信并不是所有网站都能直接接入,而是要去微信后台开通这个权限。 至少要提前向认证中心申请的几个参数如下: 1、请求授权码 客户端需要向认证中心拿到授权码,比如第三方登录使用微信,扫一扫登录那一步就是向微信的认证中心获取授权码。 请求的url如下: 上述这个url中携带的几个参数如下: 2、返回授权码 第1步请求之后,认证中心会要求登录、是否同意授权,用户同意授权之后直接跳转到 上述链接中的 3、请求令牌 客户端拿到授权码之后,直接携带授权码发送请求给认证中心获取令牌,请求的url如下: 相同的参数同上,不同参数解析如下: 4、返回令牌 认证中心收到令牌请求之后,通过之后,会返回一段JSON数据,其中包含了令牌access_token,如下: access_token则是颁发的令牌,refresh_token是刷新令牌,一旦令牌失效则携带这个令牌进行刷新。 这种模式不常用,主要针对那些无后台的系统,直接通过web跳转授权,流程如下图: 这种方式把令牌直接传给前端,是很不安全的。因此,只能用于一些安全要求不高的场景,并且令牌的有效期必须非常短,通常就是会话期间(session)有效,浏览器关掉,令牌就失效了。 1、请求令牌 客户端直接请求令牌,请求的url如下: 这个url正是授权码模式中获取授权码的url,各个参数解析如下: 2、返回令牌 认证中心认证通过后,会跳转到redirect_uri,并且后面携带着令牌,链接如下: 密码模式也很简单,直接通过用户名、密码获取令牌,流程如下: 1、请求令牌 认证中心要求客户端输入用户名、密码,认证成功则颁发令牌,请求的url如下: 参数解析如下: 2、返回令牌 上述认证通过,直接返回JSON数据,不需要跳转,如下: access_token则是颁发的令牌,refresh_token是刷新令牌,一旦令牌失效则携带这个令牌进行刷新。 适用于没有前端的命令行应用,即在命令行下请求令牌。 这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。 流程如下: 1、请求令牌 请求的url为如下: 参数解析如下: 2、返回令牌 认证成功后直接返回令牌,格式为JSON数据,如下: 为了方便测试OAuth2的四种授权模式,这里为了方便测试,简单搭建一个认证中心,后续会逐渐完善。 陈某使用的是Spring Boot + Spring Cloud Alibaba 作为基础搭建,新建一个 案例源码已经上传GitHub,关注公众号:码猿技术专栏,回复关键词 9529 获取。 Spring Boot 和 Spring Cloud 的相关依赖这里陈某就不再说了,直接上Spring Security和OAuth2的依赖,如下: 这里主要涉及到Spring Security的配置。 1、加密方式 采用BCryptPasswordEncoder加密,如下: 2、配置用户 这里为了方便测试,直接将用户信息存储在内存中,后续完善,代码如下: 上述代码配置了两个用户,如下: 3、注入认证�
为什么需要OAuth2.0?
令牌和密码的区别?
什么是OAuth2?
OAuth2.0的四种模式?
1、授权码模式
/oauth/authorize?client_id=&response_type=code&scope=&redirect_uri=
code=xxx
,这就是授权码
redirect_uri
(这个需要事先在认证中心申请配置),授权码会携带在这个地址后面,如下:http://xxxx?code=NMoj5y
NMoj5y
就是授权码了。/oauth/token?
client_id=&
client_secret=&
grant_type=authorization_code&
code=NMoj5y&
redirect_uri=
{
"access_token":"ACCESS_TOKEN",
"token_type":"bearer",
"expires_in":2592000,
"refresh_token":"REFRESH_TOKEN",
"scope":"read",
"uid":100101
}2、简化模式
/oauth/authorize?
response_type=token&
client_id=CLIENT_ID&
redirect_uri=CALLBACK_URL&
scope=
https://xxxx#token=NPmdj5
#token=NPmdj5
这一段后面携带的就是认证中心携带的,令牌为NPmdj5。3、密码模式
/oauth/token?
grant_type=password&
username=&
password=&
client_id=&
client_secret=
{
"access_token":"ACCESS_TOKEN",
"token_type":"bearer",
"expires_in":2592000,
"refresh_token":"REFRESH_TOKEN",
"scope":"read",
"uid":100101
}4、客户端模式
/oauth/token?
grant_type=client_credentials&
client_id=&
client_secret=
{
"access_token": "ACCESS_TOKEN",
"token_type": "bearer",
"expires_in": 7200,
"scope": "all"
}OAuth2.0的认证中心搭建
1、案例架构
oauth2-auth-server-in-memory
模块作为认证中心,目录如下:
“
2、添加依赖
<!--spring security的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--OAuth2的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>3、Spring Security安全配置
SecurityConfig
这个配置类中主要设置有4块内容,如下: