有妹子留言说看了很多文章,始终没明白OAuth2.0,这次陈某花了两天时间,整理了OAuth2.0相关的知识,结合认证授权服务+资源服务,一次性给大家唠明白!
本篇文章介绍一下OAuth2.0相关的知识点,并且手把手带大家搭建一个认证授权中心、资源服务进行OAuth2.0四种授权模式的验证,案例源码详细,一梭子带大家了解清楚。
本篇文章的案例源码项目架构为:Spring Boot + Spring Cloud Alibaba + Spring Security ,Spring Cloud Alibaba有不了解可以看下陈某的往期
文章目录如下:
编码永远都是为了解决生产中的问题,想要理解为什么需要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如下:
/oauth/authorize?client_id=&response_type=code&scope=&redirect_uri=
上述这个url中携带的几个参数如下:
code=xxx
,这就是授权码2、返回授权码
第1步请求之后,认证中心会要求登录、是否同意授权,用户同意授权之后直接跳转到redirect_uri
(这个需要事先在认证中心申请配置),授权码会携带在这个地址后面,如下:
http://xxxx?code=NMoj5y
上述链接中的NMoj5y
就是授权码了。
3、请求令牌
客户端拿到授权码之后,直接携带授权码发送请求给认证中心获取令牌,请求的url如下:
/oauth/token?
client_id=&
client_secret=&
grant_type=authorization_code&
code=NMoj5y&
redirect_uri=
相同的参数同上,不同参数解析如下:
4、返回令牌
认证中心收到令牌请求之后,通过之后,会返回一段JSON数据,其中包含了令牌access_token,如下:
{
"access_token":"ACCESS_TOKEN",
"token_type":"bearer",
"expires_in":2592000,
"refresh_token":"REFRESH_TOKEN",
"scope":"read",
"uid":100101
}
access_token则是颁发的令牌,refresh_token是刷新令牌,一旦令牌失效则携带这个令牌进行刷新。
这种模式不常用,主要针对那些无后台的系统,直接通过web跳转授权,流程如下图:
简化模式
这种方式把令牌直接传给前端,是很不安全的。因此,只能用于一些安全要求不高的场景,并且令牌的有效期必须非常短,通常就是会话期间(session)有效,浏览器关掉,令牌就失效了。
1、请求令牌
客户端直接请求令牌,请求的url如下:
/oauth/authorize?
response_type=token&
client_id=CLIENT_ID&
redirect_uri=CALLBACK_URL&
scope=
这个url正是授权码模式中获取授权码的url,各个参数解析如下:
2、返回令牌
认证中心认证通过后,会跳转到redirect_uri,并且后面携带着令牌,链接如下:
https://xxxx#token=NPmdj5
#token=NPmdj5
这一段后面携带的就是认证中心携带的,令牌为NPmdj5。
密码模式也很简单,直接通过用户名、密码获取令牌,流程如下:
密码模式
1、请求令牌
认证中心要求客户端输入用户名、密码,认证成功则颁发令牌,请求的url如下:
/oauth/token?
grant_type=password&
username=&
password=&
client_id=&
client_secret=
参数解析如下:
2、返回令牌
上述认证通过,直接返回JSON数据,不需要跳转,如下:
{
"access_token":"ACCESS_TOKEN",
"token_type":"bearer",
"expires_in":2592000,
"refresh_token":"REFRESH_TOKEN",
"scope":"read",
"uid":100101
}
access_token则是颁发的令牌,refresh_token是刷新令牌,一旦令牌失效则携带这个令牌进行刷新。
适用于没有前端的命令行应用,即在命令行下请求令牌。
这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。
流程如下:
客户端模式
1、请求令牌
请求的url为如下:
/oauth/token?
grant_type=client_credentials&
client_id=&
client_secret=
参数解析如下:
2、返回令牌
认证成功后直接返回令牌,格式为JSON数据,如下:
{
"access_token": "ACCESS_TOKEN",
"token_type": "bearer",
"expires_in": 7200,
"scope": "all"
}
为了方便测试OAuth2的四种授权模式,这里为了方便测试,简单搭建一个认证中心,后续会逐渐完善。
陈某使用的是Spring Boot + Spring Cloud Alibaba 作为基础搭建,新建一个oauth2-auth-server-in-memory
模块作为认证中心,目录如下:
“案例源码已经上传GitHub,关注公众号:码猿技术专栏,回复关键词 9529 获取。
”
Spring Boot 和 Spring Cloud 的相关依赖这里陈某就不再说了,直接上Spring Security和OAuth2的依赖,如下:
<!--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>
SecurityConfig
这个配置类中主要设置有4块内容,如下:
1、加密方式
采用BCryptPasswordEncoder加密,如下:
2、配置用户
这里为了方便测试,直接将用户信息存储在内存中,后续完善,代码如下:
上述代码配置了两个用户,如下:
3、注入认证管理器AuthenticationManager
AuthenticationManager
在密码授权模式下会用到,这里提前注入,如果你用的不是密码模式,可以不注入,代码如下:
4、配置安全拦截策略
由于需要验证授权码模式,因此开启表单提交模式,所有url都需要认证,代码如下:
令牌支持多种方式存储,比如内存方式、Redis、JWT,比较常用的两种则是Redis、JWT。
这里暂时使用内存存储的方式,一旦服务器重启令牌将会失效。
代码如下:
不是所有配置类都可以作为OAuth2.0认证中心的配置类,需要满足以下两点:
代码如下:
AuthorizationServerConfigurerAdapter需要实现的三个方法如下:
下面便是围绕这三个方法进行OAuth2的详细配置。
在介绍OAuth2.0 协议的时候介绍到,并不是所有的客户端都有权限向认证中心申请令牌的,首先认证中心要知道你是谁,你有什么资格?
因此一些必要的配置是要认证中心分配给你的,比如客户端唯一Id、秘钥、权限。
客户端配置的存储也支持多种方式,比如内存、数据库,对应的接口为:org.springframework.security.oauth2.provider.ClientDetailsService,接口如下:
同样这里为了方便测试,依然是加载在内存中,后续完善,完整的配置如下:
几个重要参数说一下,如下:
.withClient("myjszl")
:指定客户端唯一ID为myjszl
.secret()
:指定秘钥,使用加密算法加密了,秘钥为123
.resourceIds("res1")
:给客户端分配的资源权限,对应的是资源服务,比如订单这个微服务就可以看成一个资源,作为客户端肯定不是所有资源都能访问。
authorizedGrantTypes()
:定义认证中心支持的授权类型,总共支持五种
授权码模式:authorization_code
密码模式:password
客户端模式:client_credentials
简化模式:implicit
令牌刷新:refresh_token,这并不是OAuth2的模式,定义这个表示认证中心支持令牌刷新
scopes()
:定义客户端的权限,这里只是一个标识,资源服务可以根据这个权限进行鉴权。
autoApprove
:是否需要授权,设置为true则不需要用户点击确认授权直接返回授权码
redirectUris
:跳转的uri
使用授权码模式必须配置一个授权码服务,用来颁布和删除授权码,当然授权码也支持多种方式存储,比如内存,数据库,这里暂时使用内存方式存储,代码如下:
除了令牌的存储策略需要配置,还需要配置令牌的服务AuthorizationServerTokenServices
用来创建、获取、刷新令牌,代码如下:
目前这里仅仅配置了四个,分别如下:
/oauth/token
申请令牌的uri只允许POST提交。详细代码如下:
spring Security框架默认的访问端点有如下6个:
当然如果业务要求需要改变这些默认的端点的url,也是可以修改的,AuthorizationServerEndpointsConfigurer
有一个方法,如下:
public AuthorizationServerEndpointsConfigurer pathMapping(String defaultPath, String customPath)
第一个参数:需要替换的默认端点url
第二个参数:自定义的端点url
主要对一些端点的权限进行配置,代码如下:
客户端申请令牌的目的就是为了访问资源,当然这个资源也是分权限的,一个令牌不是所有资源都能访问的。
在认证中心搭建的第6步配置客户端详情的时候,一行代码.resourceIds("res1")
则指定了能够访问的资源,可以配置多个,这里的res1则是唯一对应一个资源。
陈某使用的是Spring Boot + Spring Cloud Alibaba 作为基础搭建,新建一个oauth2-auth-resource-in-memory
模块作为认证中心,目录如下:
“案例源码已经上传GitHub,关注公众号:码猿技术专栏,回复关键词 9529 获取。
”
作为资源服务的配置类必须满足两个条件,如下:
@EnableResourceServer
ResourceServerConfigurerAdapter
代码如下:
由于认证中心使用的令牌存储策略是在内存中的,因此服务端必须远程调用认证中心的校验令牌端点**/oauth/check_token**进行校验。
代码如下:
“注意:远程校验令牌存在性能问题,但是后续使用JWT令牌则本地即可进行校验,不必远程校验了。
”
上文说到客户端有一个唯一标识,因此需要配置上,代码如下:
上文在认证中心的第6步配置客户端详情那里,有一行代码.scopes("all")
则是指定了客户端的权限,资源服务可以根据这个scope进行url的拦截。
拦截方式如下:
.access("#oauth2.hasScope('')")
详细配置代码如下:
这里陈某配置了所有路径都需要all的权限。
新建了两个接口,如下:
/hello
:认证成功都可以访问/admin
:只有具备ROLE_admin角色的用户才可以访问下面结合认证中心、资源服务对OAuth2.0的四种服务进行测试。
启动上述搭建的认证中心和资源服务,如下图:
1、获取授权码
请求的url如下:
http://localhost:2003/auth-server/oauth/authorize?client_id=myjszl&response_type=code&scope=all&redirect_uri=http://www.baidu.com
浏览器访问,security需要登录,如下:
输入用户名user,密码123,成功登录。
此时来到了确认授权的页面,如下:
选择Apporove、确认授权,成功跳转到了百度页面,并且携带了授权码,如下:
这里的6yV2bF就是获取到的授权码。
2、获取token
http://localhost:2003/auth-server/oauth/token?code=jvMH5U&client_id=myjszl&client_secret=123&redirect_uri=http://www.baidu.com&grant_type=authorization_code
注意:/oauth/token获取token的接口请求允许的方式要配置在授权服务器中,比如配置POST方式,代码如下:
.allowedTokenEndpointRequestMethods(HttpMethod.POST)
POSTMAN请求如下图:
3、访问资源服务
拿着令牌访问资源服务的**/hello**接口,请求如下:
请求头需要添加Authorization,并且值为Bearer+" "+access_token的形式。
注意:Bearer后面一定要跟一个空格。
密码模式比较简单,不用先获取授权码,直接使用用户名、密码获取token。
POSTMAN请求如下:
PS:访问资源自己拿着获取到的令牌尝试下.....
简化模式就很简单了,拿着客户端id就可以获取token,请求的url如下:
http://localhost:2003/auth-server/oauth/authorize?response_type=token&client_id=myjszl&redirect_uri=http://www.baidu.com&scope=all
这个过程和获取授权码一样,需要登录,同意授权
最终跳转到百度,链接后面直接携带了令牌,如下:
上图中的0d5ecf06-b255-4272-b0fa-8e51dde2ce3e则是获取的令牌。
PS:访问资源自己尝试下..........
请求的url如下:
http://localhost:2003/auth-server/oauth/token?client_id=myjszl&client_secret=123&grant_type=client_credentials
POSTMAN请求如下:
PS:访问资源自己尝试下..........
Spring Security OAuth2.0还提供了其他的端点,下面来逐一测试一下。
OAuth2.0提供了令牌刷新机制,一旦access_token过期,客户端可以拿着refresh_token去请求认证中心进行令牌的续期。
请求的url如下:
http://localhost:2003/auth-server/oauth/token?client_id=myjszl&client_secret=123&grant_type=refresh_token&refresh_token=
POSTMAN请求如下:
OAuth2.0还提供了校验令牌的端点,请求的url如下:
http://localhost:2003/auth-server/oauth/check_token?toke=
POSTMAN请求如下:
本文介绍了OAuth2.0协议原理、四种授权模式,并且搭建了认证授权中心、资源服务进行了四种模式的测试。
作为OAuth2.0入门教程已经非常详细了..........
本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/lCExO5BFXmyZpPCWJ7zSXQ
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。