SpringSecurity(十五)---OAuth2的运行机制(上)-OAuth2概念和授权码模式讲解

news2024/11/24 11:25:13

一、前言

鸽了很久,其实也因为自己确实比较忙,加之自己在造demo的时候也遇到了很多问题,并且网上这方面的解答非常之少,不过也正是因为少,才更加让我想写这样的知识分享,最终,在一篇博客的解答下解决了问题,本节我们就开始Oauth2的学习。在之前的学习中,我们可以说SpringSecurity本身的基础学习差不多告一段落,大家已经可以通过自己的能力去搭建一个SpringSecurity的安全应用。
那么接下来我们就接着学习OAuth2这样一个庞大的主题,我们在这一章主要介绍一个概要,即OAuth2是什么,然后将会把它应用到一个关注使用单点登录(SSO)进行身份验证的应用程序上。这里之所以选用SSO,是因为其非常简单,也非常有用。

二、OAuth2框架

在大多数情况下,OAuth2被称为授权框架(或规范框架),其主要目的是允许第三方网站或应用程序访问资源。有时人们也把OAuth2称为一项委托协议。无论如何称呼它,重要的是要记住OAuth2不是一个特定的实现或库。也可以将OAuth2流程定义应用于其他平台、工具或语言。这里将介绍如何实现OAuth2与SpringBoot和Spring Security的集成应用。
 理解OAuth2我们可以通过和之前学习过的HTTP Basic身份验证方法进行对比,我们以前使用的是HTTP Basic身份言则会那个,它有以下两个问题:

  • 为每个请求发送凭据
  • 由单独的系统管理用户的凭据

为每个请求发送凭据可能只适用于隔离环境的情况,但这通常是不可取的,因为这意味着:

  • 需要经常在网络上共享凭据
  • 让客户端(就Web应用程序而言就是浏览器)以某种方式存储凭据,以便客户端可以将这些凭据发送到服务器,并请求进行身份验证和授权。

我们希望在应用程序的架构中去掉这两点,因为它们会使凭据变成漏洞,从而削弱安全性。通常,我们会希望有一个单独的系统管理系统用户凭据。假设我们必须为组织中使用的所有应用程序配置和使用单独的凭据。如下图:在组织中,通常会使用多个应用程序。其中大多数需要用户进行身份验证才能使用。用户需要记住多个密码,组织要管理多个凭据集合,这将是一项挑战。
在这里插入图片描述
如果将凭据管理的职责隔离在系统的一个组件中会更好。目前,我们将其称为授权服务器。如下图:它拥有更易于维护的架构会将凭据单独保存,并允许所有应用程序为其用户使用同一组凭据
在这里插入图片描述
这种方式消除了表示同一个人的重复凭据。通过这种方式,架构将变得简单。

三、OAuth2身份验证架构的组件

  • 资源服务器托管用户所拥有的资源的应用程序。资源可以是用户的数据或他们被授权的操作
  • 用户(也成为资源拥有者):拥有由资源服务器暴露的资源的个体。用户通常有一个用户名和密码,他们用用户名和密码标识自己。
  • 客户端:以用户名义访问用户所拥有的资源的应用程序客户端使用客户端ID和客户端密钥来标识自己。请注意,这些凭据与用户凭据不同。客户端在发出请求时需要自己的凭据来标识自己
  • 授权服务器授权客户端访问由资源服务器暴露的用户资源的应用程序当授权服务器决定授权客户端已用户名义访问资源时,它会发出一个令牌客户端使用此令牌向资源服务器证明他已被授权服务器授权。如果它有一个有效的令牌,则资源服务器将允许客户端访问它请求的资源

在这里插入图片描述

四、使用OAuth2的实现选项

OAuth2主要是指使用令牌进行授权。令牌就像门禁卡一样。一旦获得令牌,就可以访问特定的资源。但是OAuth2提供了多种可能性以便获取令牌也称为授权。以下是可以选择的最常见的OAuth2授权方式。

  • 授权码
  • 密码
  • 刷新令牌
  • 客户端凭据

4.1、实现授权码授权类型

这种授权类型是最常用的OAuth2流程之一。
在这里插入图片描述
如上图,授权代码授权类型。客户端会要求用户直接与授权服务器交互,以便为其授予用户请求的权限。在授权之后,授权服务器会发出令牌,这样客户端就可以使用该令牌访问用户的资源。
ps:上图中的箭头不一定表示HTTP请求和响应。这些箭头表示OAuth2的参与者之间交换的消息。例如,当客户端告知用户“告知授权服务器你允许我做这个操作”时,客户端就会将用户重定向到授权服务器登录页面。当授权服务器向客户端提供访问令牌时,授权服务器实际上会根据所谓的重定向URI来调用客户端。当然这些细节后面会讲到,这里只需知道这些序列图不仅仅表示HTTP请求和响应,它们是对OAuth2参与者之间通信的简化描述

以下是授权码授权类型的工作方式。接下来将详细深入讲解每个步骤的细节。
(1)发出身份验证请求
(2)获取访问令牌
(3)调用受保护的资源

步骤1:使用授权码授权类型发出身份验证请求

客户端将用户重定向到需要进行身份验证的授权服务器端点。假设我们正在使用应用程序X,并且需要访问一个受保护的资源。为了访问该资源,应用程序X需要我们进行身份验证。它会打开一个授权服务器上的页面,其中包含登录表单,我们必须用凭据填写该表单
ps:这里真正需要注意的是,用户会直接与授权服务器交互。用户不会向客户端应用程序发送凭据
从技术上讲,这里发生的处理是,当客户端将用户重定向到授权服务器时,客户端会调用授权端点,并在请求中使用以下详细信息。

  • 带有code值的response_type,它会告知授权服务器客户端需要一个授权码。客户端需要该授权码用来获取访问令牌,第(2)步中将会接受。
  • client_id具有客户端ID值,它会标识应用程序本身
  • redirect_uri它会告知授权服务器在成功进行身份验证之后将用户重定向到何处。有时授权服务器已经知道每个客户端的默认重定向URI。由于这个原因,客户端不需要发送重定向URI。
  • scope,它类似于被授予的权限
  • state,他定义了一个跨站请求伪造(CSRF)令牌。用以CSRF防护
    拿一个后面实例中这一步出现的链接说明:
    在这里插入图片描述
    这一步就是客户端将用户重定向到授权服务器的场景,此时客户端向授权服务器(这里是gitee)发送请求,请求链接为:

https://gitee.com/oauth/authorize?response_type=code&client_id=c70egngnghhn464541b580db179d027df1f3017797e053890edd&scope=user_info&state=x5dLt6OkIRluOTVN4UQXG4mds5tqJBokhAd140_nqog%3D&redirect_uri=http://localhost:9090/login/oauth2/code/gitee

大家对比一下就会发现和上面的元素是一样的
身份验证成功后,授权服务器将根据重定向URI回调客户端,并提供授权码和状态值。客户端要检查状态值是否与它在请求中发送的状态值相同,以确认不是其他人试图调用重定向URI。之后客户端会使用授权码获取第(2)步中所示的访问令牌。

步骤2:使用授权码授权类型获取访问令牌

为了允许用户访问资源,第(1)步所产生的授权码就是经过身份验证的用户的客户端证明。没错,这就是它被称为授权码类型的原因。现在客户端将使用该授权码调用授权服务器以获取令牌
PS:在第一步中,交互发生在用户和授权服务器之间。而在这个步骤中,交互是在客户端和授权服务器之间进行的
在这里插入图片描述
你可能会好奇,为什么流程需要对授权服务器进行两次调用并且得到两个不同的令牌——授权码和访问令牌。花点时间理解这一点:

  • 授权服务器生成第一个授权码作为用户直接与之交互的证明。客户端接收到此授权码,并且必须再次使用该授权码及其凭据进行身份验证,以获得访问令牌。
  • 客户端使用第二个令牌访问资源服务器上的资源

那么授权服务器为什么不直接返回访问令牌呢?OAuth2定义了一个被称为隐式授权类型的流程,授权服务器会在其中直接返回访问令牌。该隐式授权类型后面不会去进行讲解,因为不建议使用,而且如今大多数授权服务器都不允许使用。授权服务器将使用访问令牌直接调用重定向URI,而不会确保接收该令牌的确实是正确的客户端,这一简单事实会降低流程的安全性通过首先发送授权码,客户端必须再次使用其凭据来证明其身份,以便获得令牌。客户端会进行最后一次调用以获取访问令牌并在其中发送:

  • 授权码,这会证明用户对客户端进行了授权
  • 客户端的凭据,这将证明它们确实是同一个客户端,而不是其他人截获了授权码

从技术上讲,客户端现在会向授权服务器发出请求。该请求包含以下详细信息:

  • code,这是步骤1中接收到的授权码。这将证明用户经过了身份验证。
  • client_id和client_secret,它们是客户端的凭据。
  • redirect_uri,它与步骤1中用于验证的重定向URI相同。
  • 具有authorization_code值得grant_type,它会标识所使用的的流程的类型。服务器可能支持多个流程,因此必须始终指定当前要执行哪个身份验证流程。

作为响应,服务器会返回一个access_token这个令牌是一个客户端可用来调用由资源服务器暴露的资源的值

步骤3:使用授权码授权类型调用受保护资源

在成功地从授权服务器获得访问令牌之后,客户端现在就可以调用受保护的资源了。在调用资源服务器的端点时,客户端要在授权请求头中使用访问令牌。
我将接口所经历的步骤总结成下图:
在这里插入图片描述
客户端从进行第三方认证操作的起点,默认格式为{baseUrl}/oauth2/authorization/{clientRegistrationId},其中clientRegistrationId代表着一个第三方标识,可以是微信、支付宝等开放平台,这里为gitee。用户点击了这个请求后就开始了授权之旅。
也就有了客户端向客户重定向的第②步,然后第⑤步就是向授权服务器(gitee)去获取授权码,然后用户通过认证同意授权后,授权服务器将客户重定向到通过配置的发回授权码的redirectUri发回授权码,
用户此时通过这个Url将授权码发给了客户端,客户端通过该授权码通过⑩请求获取accessToken
那么更详细的,也是我参考过觉得不错的文章有下面2篇,大家可以去看一下:

https://blog.csdn.net/longlivechina008/article/details/125007457
https://www.cnblogs.com/felordcn/p/13952072.html

其中上图中Client客户端中的OAuthFilter相当于之前SpringSecurity流程中的AuthenticationManager->AuthenticationProvider->UserDetailsService层层返回UserDetails到Filter,然后Filter将UserDetails打包为Authentication然后放到SecurityContext安全上下文中供后续使用,然后结束filterChain到达。
授权码是使用频率非常高的一种授权类型,大家需要好好吸收,尤其是概念,后面我们还会通过授权码授权类型的一个实例-sso单点登录去让大家印象更加深刻。
授权码授权类型的最大优点是让用户可以允许客户端执行特定的操作,而不需要与客户端共享其凭据,不过,这种授权类型有一个缺点:如果有人截获授权码,会发生什么?当然,如之前所属,客户端需要使用其凭据进行身份验证。但是,如果客户端凭据也以某种方式被盗了呢?即使这种情况非常罕见,但是我们也可以认为它是这种授权类型的漏洞。要避免这个漏洞,就需要借助PKCE授权码授权类型所提供的更复杂的场景,大家有兴趣可以自行了解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/28256.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中文drupal教程(4)Session会话系统

Session(会话)在网站中扮演非常重要的角色,储存临时用户数据、登录数据等等都用到了它,Drupal使用到了Symfony的Session组件,该组件非常强大灵活,drupal在此基础上有所改造和扩展,要理解Symfony…

企业微信接口测试实战(一)

本文为在霍格沃兹测试开发学社中学习到的一些技术,写出来分享给大家,希望有志同道合的小伙伴可以一起交流技术,一起进步~ 霍格沃茨启发: 测试开发进阶班>接口自动化测试>企业微信接口测试实战 企业微信接口测试实战 一、准备环境二、脚本实现2.1、 获得access_token2…

防火墙用户管理理论+实验

目录 注:实验需要有安全策略配置、NAT配置基础 一、防火墙用户管理重要知识点 用户管理 访问控制策略 NGFW下一代防火墙 AAA 鉴别方式——认证 用户认证的分类: 上网用户上线流程: 二、用户认证实验: 实验拓扑 先配置防…

pmp考试是什么?

PMP是一个全球资格认证,也是目前项目管理领域大家公认的证书,相当于项目管理的入门证书。 一、PMP 是什么 pmp 中文叫项目管理专业人士资格认证,目前项目管理领域大家公认的证书,是一个用来评估项目管理人员的知识技能是否已经达…

D. Divide and Summarize(BFS+二分+预处理)

Problem - 1461D - Codeforces 迈克收到一个长度为n的数组作为生日礼物,决定测试一下它的漂亮程度。 如果有一种方法可以通过一定数量(可能是零)的切片操作得到一个元素总和为si的数组,那么这个数组将通过第i次漂亮度测试。 一个…

红红火火的VB,悄然离去,新型中文编程,如日中天

“悲哀!现在用VB连1200都赚不到。”一位VB程序员有感而发。曾经红红火火的VB编程语言,如今却徘徊在被淘汰边缘,让人惋惜。 依稀记得,读大学时候,有一位财务专业同学,特别喜欢计算机,有空就自学V…

密码学引论 | DES

文章目录DES算法1 算法流程2 算法细节(1)子密钥的产生(2)初始置换IPIPIP(3)加密函数(4)逆初始置换IP−1IP^{-1}IP−1例题DES算法 1 算法流程 64位密钥经子密钥产生算法产生出16个子…

用 TypeScript 类型运算实现一个五子棋游戏

之前有看到有大佬用类型运算实现了中国象棋程序 和 Lisp 解释器 甚是震惊,之前不太会看不懂。 最近也学了点类型体操的内容想着自己也玩一下。选择五子棋的原因是相对来说规则是更简单一些的也比较好实现。此实现没有考虑性能上优化和最佳实现方式只关注功能的实现…

详细步骤讲解matlab代码通过Coder编译为c++并用vs2019调用

项目上需要C,奈何本人不会,所以就用matlab写好测试后,用matlab Coder编译为c并用vs2019调用 一个简单的例子,求取两个4*4矩阵相加后,在求取最大值与最小值。matlab代码如下 function [a,b] min_max(m,n)temp mn;a m…

STM32F407 电机编码器测量

文章目录一、STM32F407 定时器编码器功能1.1 STM32定时器简介1.2 STM32定时器编码器功能二、带编码器的直流电机三、代码与验证3.1 初始化代码3.2 验证一、STM32F407 定时器编码器功能 1.1 STM32定时器简介 STM32的定时器功能非常强大,根据官方手册,定…

旅游网页设计 web前端大作业 全球旅游私人订制 旅游公司网站模板(HTML+CSS+JavaScript)

👨‍🎓学生HTML静态网页基础水平制作👩‍🎓,页面排版干净简洁。使用HTMLCSS页面布局设计,web大学生网页设计作业源码,这是一个不错的旅游网页制作,画面精明,排版整洁,内容…

OctaneRender界面布局自定义界面教程丨使用教程

您可以通过单击并拖动每个窗格左上角的方块(图 1)来重新排列 OctaneRender 界面(图形编辑器、渲染视口、节点检查器和大纲视图)中每个窗格的窗口。 图 1:窗格排列图标 用任何鼠标按钮单击同一个方块会显示更多用于…

SpringBoot SpringBoot 开发实用篇 5 整合第三方技术 5.20 ActiveMQ 安装

SpringBoot 【黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)】 SpringBoot 开发实用篇 文章目录SpringBootSpringBoot 开发实用篇5 整合第三方技术5.20 ActiveMQ 安装5.20.1 下载5.20.2 安装5.20.3 使…

[附源码]SSM计算机毕业设计基于的城镇住房公积金管理系统JAVA

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

Unity Hair 毛发系统 初体验

文章目录🎈 简介🎈 所需环境🎈 下载安装🎈 使用初体验🍭 创建一个Hair示例🍭 Hair Asset🍭 尝试给Avatar创建头发🍭 如何更改材质🎈 简介 8月份的时候Unity官方发布了Ha…

第7章 Elasticsearch面试题

7 . 1 为什么要使用Elasticsearch? 系统中的数据,随着业务的发展,时间的推移,将会非常多,而业务中往往采用模糊查询进行数据的搜索,而模糊查询会导致查询引擎放弃索引,导致系统查询数据时都是全表扫描&am…

即将见面:SpreadJS V16:重大改进

内容摘自互联网::::::: 新功能背景:在SpreadJS V16之前,关于文件toJSON()之后,生成的json文件太大,一直被很多客户诟病。例如,同样一…

PySide创建界面关联项目(五) 百篇文章学PyQT

本文章是百篇文章学PyQT的第五篇,本文讲述如何使用PySide创建UI界面,并且关联入PyCharm 新建的项目中成功运行第一个PyQT程序,博主在本篇文章中将遇到和踩过的坑总结出来,可以供大家参考,希望大家安装顺利。包括 安装、…

我的Vue组件化开发首个项目todolist

TodoList 学习笔记: 总结TodoList案例 1.组件化编码流程: (1).拆分静态组件:组件要按照功能点拆分,命名不要与htm|元素冲突。 (2).实现动态组件:考虑好数据的存放位置,数据是一个组件在用, 还是一些组件在用: . 1).-个组件在…

Vue简单实例——从webpack到vue,再到weex

这一章节,我们主要针对从webpack,vue,weex的框架结构上来说明对比这三个框架的区别 主要功能: webpack: webpack是前端项目工程化的具体解决方案。 它提供了友好的前端模块化开发支持,以及代码压缩混淆&…