基于Spring Security 6的OAuth2 系列之八 - 授权服务器--Spring Authrization Server的基本原理

之所以想写这一系列,是因为之前工作过程中使用Spring Security OAuth2搭建了网关和授权服务器,但当时基于spring-boot 2.3.x,其默认的Spring Security是5.3.x。之后新项目升级到了spring-boot 3.3.0,结果一看Spring Security也升级为6.3.0。无论是Spring Security的风格和以及OAuth2都做了较大改动,里面甚至将授权服务器模块都移除了,导致在配置同样功能时,花费了些时间研究新版本的底层原理,这里将一些学习经验分享给大家。

注意由于框架不同版本改造会有些使用的不同,因此本次系列中使用基本框架是 spring-boo-3.3.0(默认引入的Spring Security是6.3.0),JDK版本使用的是19,本系列OAuth2的代码采用Spring Security6.3.0框架,所有代码都在oauth2-study项目上:https://github.com/forever1986/oauth2-study.git

目录

  • 1 关键的类
    • 1.1 Authentication
    • 1.2 AuthenticationConverter
    • 1.3 AuthenticationProvider
  • 2 授权码模式的底层原理
  • 3 授权码模式整体流程图
  • 4 关键的Filter过滤器
    • 4.1 OAuth2AuthorizationEndpointFilter(授权码code请求处理)
    • 4.2 OAuth2TokenEndpointFilter(返回token)
    • 4.3 OAuth2ClientAuthenticationFilter(客户端认证)

前面我们了解授权服务器的实现以及自定义客户端、自定义授权页面,也窥探了其中部分原理。这一章,我们通过授权码模式下,分析一下Spring Authrization Server的基本原理,同时对其中一些关键的Filter过滤器列出来,对后续实现功能会有帮助。我们知道Spring Authrization Server也是基于Spring Security 6基础上实现的,因此其关键功能都在其过滤器上面。下图红色框框的是Spring Authrization Server新增的过滤器,我们挑一些关键的解释一下

在这里插入图片描述

1 关键的类

在介绍关键的过滤器之前,有几个类需要先说明一下其作用,对后面阅读源码有很好的理解。

1.1 Authentication

Authentication其实是Spring Security的接口,主要就是封装认证信息,用于上下文传输,而在Spring Authrization Server中,有几个实现类比较重要:

  • OAuth2AuthorizationCodeRequestAuthenticationToken:在授权码模式下,获取授权码时候封装的信息
  • OAuth2AuthorizationConsentAuthenticationToken:在授权码模式下,跳转授权界面时,封装所需的信息
  • OAuth2AuthorizationCodeAuthenticationToken:在请求token时,封装所需的信息
  • OAuth2TokenExchangeAuthenticationToken:在交换token请求下,封装所需的信息
  • OAuth2RefreshTokenAuthenticationToken:在刷新token请求下,封装所需的信息

在这里插入图片描述

1.2 AuthenticationConverter

AuthenticationConverter是一个request参数转换为Authentication的一个转换器,其中有几个实现类比较重要

  • OAuth2AuthorizationCodeRequestAuthenticationConverter:在请求授权码时,将request的参数都封装为Authentication
  • OAuth2AuthorizationConsentAuthenticationConverter:在请求授权码时,点击授权页面的确认后,将request的参数都封装为Authentication
  • OAuth2AuthorizationCodeAuthenticationConverter:在请求token时,将request的参数都封装为Authentication
  • OAuth2TokenExchangeAuthenticationConverter:在交换token时,将request的参数都封装为Authentication
  • OAuth2RefreshTokenAuthenticationConverter:在刷新token时,将request的参数都封装为Authentication

在这里插入图片描述

1.3 AuthenticationProvider

AuthenticationProvider本身是Spring Security的接口,主要是用于验证结果,比如用户名密码登录等,这里Spring Authrization Server通过实现不同的AuthenticationProvider做不同验证,以下几个实现类比较重要:

  • OAuth2AuthorizationCodeRequestAuthenticationProvider:主要用于授权码模式下,客户端的验证
  • OAuth2AuthorizationConsentAuthenticationProvider:授权页面点击确认之后,客户端验证
  • OAuth2AuthorizationCodeAuthenticationProvider:获取token接口时,客户端验证
  • OAuth2TokenExchangeAuthenticationProvider:交换token接口时,客户端验证
  • OAuth2RefreshTokenAuthenticationProvider:请求刷新token接口时,客户端验证

在这里插入图片描述

2 授权码模式的底层原理

1)我们从《系列之四-客户端–oauth2-client底层原理》中可知,客户端会访问/oauth2/authorize接口,这时候会有先到达OAuth2AuthorizationEndpointFilter过滤器,但是由于未登录,因此会被认定没有权限,不做处理,继续走过滤器链。

在这里插入图片描述

在这里插入图片描述

2)接着,请求会接着跳转到AuthorizationFilter过滤器(这是Spring Security的过滤器,做认证判断的),这时候会报AccessDeniedException异常,并由LoginUrlAuthenticationEntryPoint处理,跳转到Spring Security的登录界面

在这里插入图片描述

3)出现登录界面,进行登录之后,会继续请求/oauth2/authorize接口,这时候会被OAuth2AuthorizationEndpointFilter拦截,我们再看看OAuth2AuthorizationEndpointFilter的doFilterInternal方法

在这里插入图片描述

  • 第一步:判断URI是否符合/oauth2/authorize
  • 第二步:判断客户端信息是否符合要求
  • 第三步:判断是否已经登录,没有登录,则由其它过滤器跳转到登录界面
  • 第四步:判断是否已经授权,没有授权则跳转到登录界面
  • 第五步:前面4步都没问题,则返回授权的code

下面我们将详细的源码调用过程列出来:

在这里插入图片描述

4)返回授权码给客户的之后,客户端会继续请求http://oauth-server:9000/oauth2/token获取token,而授权服务器的token由OAuth2TokenEndpointFilter过滤器处理

OAuth2TokenEndpointFilter是拦截"/oauth2/token"获取token请求,通过将request的参数封装为OAuth2AuthorizationCodeAuthenticationToken,然后调用OAuth2AuthorizationCodeAuthenticationProvider验证并生成token,通过后调用OAuth2AccessTokenResponseAuthenticationSuccessHandler返回token

在这里插入图片描述

3 授权码模式整体流程图

在这里插入图片描述

4 关键的Filter过滤器

从上面的整体流程,我们知道一些关键的Filter过滤器,这里罗列出来,后续讲解授权码其它功能时,会经常提到。

4.1 OAuth2AuthorizationEndpointFilter(授权码code请求处理)

在《系列之五 - 授权服务器–开篇》和本系列中分析过该过滤器。该过滤器专门处理/oauth2/authorize接口,在授权码模式下,该接口就是用于跳转到授权界面以及返回授权码的作用

在这里插入图片描述

4.2 OAuth2TokenEndpointFilter(返回token)

OAuth2TokenEndpointFilter是拦截"/oauth2/token"获取token请求,通过将request的参数封装为OAuth2AuthorizationCodeAuthenticationToken,然后调用OAuth2AuthorizationCodeAuthenticationProvider验证并生成token,通过后调用OAuth2AccessTokenResponseAuthenticationSuccessHandler返回token

在这里插入图片描述

4.3 OAuth2ClientAuthenticationFilter(客户端认证)

OAuth2ClientAuthenticationFilter主要是用于客户端认证,包括通过client_secret_basic、client_secret_post、client_secret_jwt、private_key_jwt、none、tls_client_auth和self_signed_tls_client_auth等不同认证方式。因此增加改拦截器用于客户端认证,其逻辑流程和OAuth2AuthorizationEndpointFilter前半部分有很大的相似,都是使用AuthenticationConverter转换参数,然后AuthenticationProvider进行验证。这块具体会在《系列之十五 - 高级特性–客户端认证方式》中详细说明。

结语:本章我们对Spring Authrization Server如何实现授权码模式以及自定义客户端信息进行源码解析,并了解了几个关键的Filter过滤器。有了这个基础,对接下来我们实现更为高级的授权服务器功能,并了解实现原理就变得更为容易。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入浅出并查集(不相交集合实现思路)

引言 并查集(Disjoint Set Union,简称DSU)是一种用于处理一些不交集的合并及查询问题。它主要支持两种操作:查找(Find)和合并(Union)。 查找:确定某个元素属于哪一个子…

如何运行Composer安装PHP包 安装JWT库

1. 使用Composer Composer是PHP的依赖管理工具,它允许你轻松地安装和管理PHP包。对于JWT,你可以使用firebase/php-jwt这个库,这是由Firebase提供的官方库。 安装Composer(如果你还没有安装的话): 访问Co…

享元模式——C++实现

目录 1. 享元模式简介 2. 代码示例 1. 享元模式简介 享元模式是一种结构型模式。 享元模式用于缓存共享对象,降低内存消耗。共享对象相同的部分,避免创建大量相同的对象,减少内存占用。 享元模式需要将对象分成内部状态和外部状态两个部分…

网络原理(4)—— 网络层详解

目录 一. IP协议报头结构 二. 地址管理 2.1 路由器 2.1.1 路由选择 2.1.2 WAN口(Wide Area Network) 2.1.3 LAN口(Local Area Network) 2.1.4 WLAN口(Wireless Local Area Network) 2.2 网段划分…

基于深度学习的输电线路缺陷检测算法研究(论文+源码)

输电线路关键部件的缺陷检测对于电网安全运行至关重要,传统方法存在效率低、准确性不高等问题。本研究探讨了利用深度学习技术进行输电线路关键组件的缺陷检测,目的是提升检测的效率与准确度。选用了YOLOv8模型作为基础,并通过加入CA注意力机…

Android --- handler详解

handler 理解 handler 是一套Android 消息传递机制,主要用于线程间通信。 tips: binder/socket 用于进程间通信。 参考: Android 进程间通信-CSDN博客 handler 就是主线程在起了一个子线程,子线程运行并生成message ,l…

vim如何解决‘’文件非法关闭后,遗留交换文件‘’的问题

过程描述: 由于我修改文件时(一定得修改了文件,不做任何修改不会产生这个问题)的非法关闭,比如直接关闭虚拟机,或者直接断开远程工具的远程连接,产生了以下遗留交换文件的问题: 点击…

六十分之三十七——一转眼、时光飞逝

一、目标 明确可落地,对于自身执行完成需要一定的努力才可以完成的 1.第三版分组、激励、立体化权限、智能设备、AIPPT做课 2.8本书 3.得到:头条、吴军来信2、卓克科技参考3 4.总结思考 二、计划 科学规律的,要结合番茄工作法、快速阅读、…

Linux环境下的Java项目部署技巧:安装 Mysql

查看 myslq 是否安装: rpm -qa|grep mysql 如果已经安装,可执行命令来删除软件包: rpm -e --nodeps 包名 下载 repo 源: http://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm 执行命令安装 rpm 源(根据下载的…

css三角图标

案例三角&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><s…

Shadow DOM举例

这东西具有隔离效果&#xff0c;对于一些插件需要append一些div倒是不错的选择 <!DOCTYPE html> <html lang"zh-CN"> <head> <meta charset"utf-8"> <title>演示例子</title> </head> <body> <style&g…

万字长文深入浅出负载均衡器

前言 本篇博客主要分享Load Balancing&#xff08;负载均衡&#xff09;&#xff0c;将从以下方面循序渐进地全面展开阐述&#xff1a; 介绍什么是负载均衡介绍常见的负载均衡算法 负载均衡简介 初识负载均衡 负载均衡是系统设计中的一个关键组成部分&#xff0c;它有助于…

ChatGPT-4o和ChatGPT-4o mini的差异点

在人工智能领域&#xff0c;OpenAI再次引领创新潮流&#xff0c;近日正式发布了其最新模型——ChatGPT-4o及其经济实惠的小型版本ChatGPT-4o Mini。这两款模型虽同属于ChatGPT系列&#xff0c;但在性能、应用场景及成本上展现出显著的差异。本文将通过图文并茂的方式&#xff0…

双指针算法思想——OJ例题扩展算法解析思路

大家好&#xff01;上一期我发布了关于双指针的OJ平台上的典型例题思路解析&#xff0c;基于上一期的内容&#xff0c;我们这一期从其中内容扩展出来相似例题进行剖析和运用&#xff0c;一起来试一下吧&#xff01; 目录 一、 基于移动零的举一反三 题一&#xff1a;27. 移除…

WSL2中安装的ubuntu开启与关闭探讨

1. PC开机后&#xff0c;查询wsl状态 在cmd或者powersell中输入 wsl -l -vNAME STATE VERSION * Ubuntu Stopped 22. 从windows访问WSL2 wsl -l -vNAME STATE VERSION * Ubuntu Stopped 23. 在ubuntu中打开一个工作区后…

git笔记-简单入门

git笔记 git是一个分布式版本控制系统&#xff0c;它的优点有哪些呢&#xff1f;分为以下几个部分 与集中式的版本控制系统比起来&#xff0c;不用担心单点故障问题&#xff0c;只需要互相同步一下进度即可。支持离线编辑&#xff0c;每一个人都有一个完整的版本库。跨平台支持…

Chapter2 Amplifiers, Source followers Cascodes

Chapter2 Amplifiers, Source followers & Cascodes MOS单管根据输入输出, 可分为CS放大器, source follower和cascode 三种结构. Single-transistor amplifiers 这一章学习模拟电路基本单元-单管放大器 单管运放由Common-Source加上DC电流源组成. Avgm*Rds, gm和rds和…

LabVIEW透镜多参数自动检测系统

在现代制造业中&#xff0c;提升产品质量检测的自动化水平是提高生产效率和准确性的关键。本文介绍了一个基于LabVIEW的透镜多参数自动检测系统&#xff0c;该系统能够在单一工位上完成透镜的多项质量参数检测&#xff0c;并实现透镜的自动搬运与分选&#xff0c;极大地提升了检…

K8S集群部署--亲测好用

最近在自学K8S&#xff0c;花了三天最后终于成功部署一套K8S Cluster集群&#xff08;masternode1node2&#xff09; 在这里先分享一下具体的步骤&#xff0c;后续再更新其他的内容&#xff1a;例如部署期间遇到的问题及其解决办法。 部署步骤是英文写的&#xff0c;最近想练…

PHP实现混合加密方式,提高加密的安全性(代码解密)

代码1&#xff1a; <?php // 需要加密的内容 $plaintext 授权服务器拒绝连接;// 1. AES加密部分 $aesKey openssl_random_pseudo_bytes(32); // 生成256位AES密钥 $iv openssl_random_pseudo_bytes(16); // 生成128位IV// AES加密&#xff08;CBC模式&#xff09…