Spring Security Oauth2 认证(获取token/刷新token)流程(password模式)

2023-11-13

1.本文介绍的认证流程范围

本文主要对从用户发起获取token的请求(/oauth/token),到请求结束返回token中间经过的几个关键点进行说明。

2.认证会用到的相关请求

注:所有请求均为post请求。

  • 获取access_token请求(/oauth/token)
    请求所需参数:client_id、client_secret、grant_type、username、password
http://localhost/oauth/token?client_id=demoClientId&client_secret=demoClientSecret&grant_type=password&username=demoUser&password=50575tyL86xp29O380t1
  • 检查头肯是否有效请求(/oauth/check_token)
    请求所需参数:token
http://localhost/oauth/check_token?token=f57ce129-2d4d-4bd7-1111-f31ccc69d4d1
  • 刷新token请求(/oauth/token)
    请求所需参数:grant_type、refresh_token、client_id、client_secret
    其中grant_type为固定值:grant_type=refresh_token
http://localhost/oauth/token?grant_type=refresh_token&refresh_token=fbde81ee-f419-42b1-1234-9191f1f95be9&client_id=demoClientId&client_secret=demoClientSecret

2.认证核心流程

注:文中介绍的认证服务器端token存储在Reids,用户信息存储使用数据库,文中会包含相关的部分代码。

2.1.获取token的主要流程:

加粗内容为每一步的重点,不想细看的可以只看加粗内容:

  1. 用户发起获取token的请求。
  2. 过滤器会验证path是否是认证的请求/oauth/token,如果为false,则直接返回没有后续操作。
  3. 过滤器通过clientId查询生成一个Authentication对象
  4. 然后会通过username和生成的Authentication对象生成一个UserDetails对象,并检查用户是否存在。
  5. 以上全部通过会进入地址/oauth/token,即TokenEndpoint的postAccessToken方法中。
  6. postAccessToken方法中会验证Scope,然后验证是否是refreshToken请求等。
  7. 之后调用AbstractTokenGranter中的grant方法。
  8. grant方法中调用AbstractUserDetailsAuthenticationProvider的authenticate方法,通过username和Authentication对象来检索用户是否存在
  9. 然后通过DefaultTokenServices类从tokenStore中获取OAuth2AccessToken对象
  10. 然后将OAuth2AccessToken对象包装进响应流返回

2.2.刷新token(refresh token)的流程

刷新token(refresh token)的流程与获取token的流程只有⑨有所区别:

  • 获取token调用的是AbstractTokenGranter中的getAccessToken方法,然后调用tokenStore中的getAccessToken方法获取token。
  • 刷新token调用的是RefreshTokenGranter中的getAccessToken方法,然后使用tokenStore中的refreshAccessToken方法获取token。

2.3.tokenStore的特点

tokenStore通常情况为自定义实现,一般放置在缓存或者数据库中。此处可以利用自定义tokenStore来实现多种需求,如:

  • 同已用户每次获取token,获取到的都是同一个token,只有token失效后才会获取新token。
  • 同一用户每次获取token都生成一个完成周期的token并且保证每次生成的token都能够使用(多点登录)。
  • 同一用户每次获取token都保证只有最后一个token能够使用,之前的token都设为无效(单点token)。

3.获取token的详细流程(代码截图)

3.1.代码截图梳理流程

1.一个比较重要的过滤器
这里写图片描述
2.此处是①中的attemptAuthentication方法
这里写图片描述
3.此处是②中调用的authenticate方法
这里写图片描述
4.此处是③中调用的AbstractUserDetailsAuthenticationProvider类的authenticate方法
这里写图片描述
5.此处是④中调用的DaoAuthenticationProvider类的retrieveUser方法
这里写图片描述
6.此处为⑤中调用的ClientDetailsUserDetailsService类的loadUserByUsername方法,执行完后接着返回执行④之后的方法
这里写图片描述
7.此处为④中调用的DaoAuthenticationProvider类的additionalAuthenticationChecks方法,此处执行完则主要过滤器执行完毕,后续会进入/oauth/token映射的方法。
这里写图片描述
8.此处进入/oauth/token映射的TokenEndpoint类的postAccessToken方法
这里写图片描述
9.此处为⑧中调用的AbstractTokenGranter类的grant方法
这里写图片描述
10.此处为⑨中调用的ResourceOwnerPasswordTokenGranter类中的getOAuth2Authentication方法
这里写图片描述
11.此处为⑩中调用的自定义的CustomUserAuthenticationProvider类中的authenticate方法,此处校验用户密码是否正确,此处执行完则返回⑨执行后续方法。
这里写图片描述
12.此处为⑨中调用的DefaultTokenServices中的createAccessToken方法
这里写图片描述
13.此处为12中调用的RedisTokenStore中的getAccessToken方法等,此处执行完,则一直向上返回到⑧中执行后续方法。
这里写图片描述
14.此处为⑧中获取到token后需要包装返回流操作
这里写图片描述

3.2.示例中spring-security.xml的部分配置

<!-- 认证地址 -->
<sec:http pattern="/oauth/token" create-session="stateless"
              authentication-manager-ref="authenticationManager" >
    <sec:intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
    <sec:anonymous enabled="false" />
    <sec:http-basic entry-point-ref="clientAuthenticationEntryPoint" />
    <sec:custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
    <sec:access-denied-handler ref="oauthAccessDeniedHandler" />
</sec:http>

<bean id="clientAuthenticationEntryPoint"
          class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <property name="realmName" value="springsec/client" />
    <property name="typeName" value="Basic" />
</bean>

<bean id="clientCredentialsTokenEndpointFilter"
      class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
    <property name="authenticationManager" ref="authenticationManager" />
</bean>

<bean id="oauthAccessDeniedHandler"
      class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler">
</bean>


<!-- 认证管理器-->
<sec:authentication-manager alias="authenticationManager">
    <sec:authentication-provider user-service-ref="clientDetailsUserService" />
</sec:authentication-manager>

<!-- 注入自定义clientDetails-->
<bean id="clientDetailsUserService"
      class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
    <constructor-arg ref="clientDetails" />
</bean>

<!-- 自定义clientDetails-->
<bean id="clientDetails" class="com.xxx.core.framework.oauth.CustomClientDetailsServiceImpl">
</bean>
<!-- 注入自定义provider-->
<sec:authentication-manager id="userAuthenticationManager">
    <sec:authentication-provider ref="customUserAuthenticationProvider" />
</sec:authentication-manager>
<!--自定义用户认证provider-->
<bean id="customUserAuthenticationProvider"
      class="com.xxx.core.framework.oauth.CustomUserAuthenticationProvider">
</bean>

<oauth:authorization-server
        client-details-service-ref="clientDetails" token-services-ref="tokenServices" check-token-enabled="true" >
    <oauth:authorization-code />
    <oauth:implicit/>
    <oauth:refresh-token/>
    <oauth:client-credentials />
    <oauth:password authentication-manager-ref="userAuthenticationManager"/>
</oauth:authorization-server>

<!-- 自定义tokenStore-->
<bean id="tokenStore"
      class="com.xxx.core.framework.oauth.RedisTokenStore" />

<!-- 设置access_token有效期,设置支持refresh_token,refresh_token有效期默认为30天-->
<bean id="tokenServices"
      class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
    <property name="tokenStore" ref="tokenStore" />
    <property name="supportRefreshToken" value="true" />
    <property name="accessTokenValiditySeconds" value="43200"></property>
    <property name="clientDetailsService" ref="clientDetails" />
</bean>

4.总结

本文中的流程能够结果的问题:

  • 需要自定义修改获取到的token
  • token单点问题
  • 使用refresh_token的情况

PS:梳理这个认证流程也是因为最近工作需要设置token超时机制,刷新token,检查token等,需要对认证这块了解的特别清楚才行,后面的代码截图只是详细的介绍了获取access_token的流程,其实refresh_token与access_token的流程基本是一样的,如果您在使用refresh_token过程中有什么问题,也可以详细看下上面的截图,或许会有一些收获。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Security Oauth2 认证(获取token/刷新token)流程(password模式) 的相关文章

随机推荐

  • 【机器视觉系统】基于3DOF机械臂的五子棋机器人(1)

    基于3DOF机械臂的五子棋机器人 文章目录 基于3DOF机械臂的五子棋机器人 1 前言 2 机器视觉系统概述 2 1 机器 2 2 视觉 2 3 系统 3 系统组成概述 3 1 使用工具盘点 3 2 流程图 4 制作步骤建议 5 需要的知识
  • 伤腰的Python爬虫案例,零基础必备实战教程

    目录 前言 开发环境介绍 爬虫案例数据采集一般步骤 1 首先第一步 找到对应的链接地址
  • 三维GIS技术应用

    三维GIS技术应用 背景 以二三维一体化GIS技术为基础框架 进一步拓展二三维一体化数据模型 融合倾斜摄影 BIM 激光点云等多源异构数据 推动三维GIS实现室外室内一体化 宏观微观一体化与空天 地表 地下一体化 赋能全空间的三维GIS应用
  • 北斗短报文遥测终端机在水雨情监测系统中的应用

    一 方案概述 我国水利监管手段比较单一 水雨情监测移动公网覆盖不足等诸多问题 利用北斗短报文通信技术 数字化信息采集技术 实现水文自动测报 大幅度提升湿地生态和水域的监测 查询 预警和应急处理能力 在恶劣天气情况或特殊灾害环境中 通过北斗卫
  • Django 缓存机制 Redis缓存

    Django 提供6种缓存方式 1 开发调式缓存 2 内存缓存 3 文件缓存 4 数据库缓存 5 Memcache缓存 使用Python memcached模块 6 Memcache缓存 使用pylibmc模块 常用的缓存方式是 文件缓存
  • 5g信令流程详解_5G无线网络信令流程

    招个电子工程师 招个电子工程师 一个只专注电子工程师精准招聘的服务 精准 快速 高效 低成本 这是 招个电子工程师 服务的精髓 如果您的技术团队需要扩军 那么 热烈欢迎各大中小企业的HR和招聘负责人与我们联系 具体合作详情请咨询 管理员微信
  • Compose 动画边学边做 - 夏日彩虹

    引言 Compose 在动画方面下足了功夫 提供了种类丰富的 API 但也正由于 API 种类繁多 如果想一气儿学下来 可能会消化不良导致似懂非懂 结合例子学习是一个不错的方法 本文就带大家边学边做 通过高仿微博长按点赞的彩虹动画 学习和实
  • 初学者如何快速练习盲打

    初学者如何快速练习盲打 2012 05 22 15 25 54 转载 标签 打字练习 初学者 手感 杂谈 分类 计算机技巧 盲打要求的是对键盘的熟练 是感觉上的东西 当你看到一句话想到的不应该是每个字有哪个拼音 有那个字母 而是像 手感 一
  • sonar扫描时报Failed to upload report - An error has occurred. Please contact your administrator

    本人新学习使用此软件 参考网络各大神资料后解决问题方法如下 此问题产生的原因在于mysql的max allowed packet 参数限制默认为4M 将设置进行修改就可以了 mysql根据配置文件会限制server接受的数据包大小 有时候大
  • 【应届生必看】技术岗面试应答有哪些话术和技巧?

    很多时候 面试过程中A与B两人工作经历 能力都相差不大时 A能脱颖而出的大部分原因是在面试过程中表现出的较高的情商 稳定性和与企业文化匹配的性格 价值观等 求职者从各项提问中了解面试官想要考察的主旨 根据自己实际情况适当地进行总结和梳理 以
  • Linux操作系统学习,Linux基础命令大全

    目录 第一章 Linux简介和安装 1 1 Linux简介和分类 1 2 安装VMware虚拟机 在虚拟机中安装CentOS 7 第二章 虚拟机中Linux的IP地址配置详解 2 1 什么是IP地址 如何查看 2 2 虚拟机NAT模式中Li
  • JCR分区与中科院分区详解-中科院基础版和升级版详解

    https baijiahao baidu com s id 1642002458698070188 wfr spider for pc JCR分区 科睿唯安每年出版JCR 期刊引用报告 JCR将收录的期刊分为176个不同学科类别 每个学科
  • ubuntu安装NERDTree,Taglist和WinManager

    在ubuntu中要用vim进行开发的话 这三个插件组合在一起 给你一种顺滑的感受 NERDTree NERDTree的安装 nerdtree可以显示当前项目的文件结构 安装方法如下 执行以下命令即可 1 创建文件夹 mkdir vim 如果
  • 线性代数的本质(五)——矩阵的运算

    文章目录 矩阵的运算 矩阵的转置 方阵的运算 初等矩阵 分块矩阵 逆矩阵 矩阵的秩 广义逆矩阵 矩阵的运算 矩阵的转置 转置 矩阵 A A A的行列互换得到的矩阵称为 A A A 的转置 transpose 记作
  • 【满分】【华为OD机试真题2023B卷 JAVA&JS】最佳植树距离

    华为OD2023 B卷 机试题库全覆盖 刷题指南点这里 最佳植树距离 知识点二分查找 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 按照环保公司要求 小明需要在沙化严重的地区进行植树防沙工作 初步目标是种植一条直线的树带
  • git报错:error: RPC failed; curl 18 transfer closed with outstanding read data remaining

    今天和朋友聊天 推荐了个项目给我看看 在克隆的过程中发现太大拉不下来 报错如下 error RPC failed curl 18 transfer closed with outstanding read data remaining 远程
  • 黄金矿工(Java)

    先来一张效果图 图片资源 https pan baidu com s 1weCGFLQlzOTvDRY18bizrg pwd ivjt 提取码 ivjt 该项目一共12个类 均处于同一目录 首先是基类 其余用来表示物体的类都继承它 impo
  • Tensorflow 1.13训练模型.pb文件转换成Tensorflowlite可以使用的.tflite文件过程记录

    Tensorflow 1 13训练模型 pb文件转换成Tensorflowlite可以使用的 tflite文件过程记录 前言 之前一直通过1 13版本的TensorflowGpu训练模型 使用范围局限在电脑端 例如opencv调用模型等等
  • unity游戏开发-socket网络通信

    本篇主要是分享基于unity的客户端socket网络通信方案 关于服务器的c socekt搭建放在了这里 基于C 的Tcp服务端通信 其中关于socekt粘包断包的处理放在这里分享了 C socket粘包断包处理 目录 整体设计 TcpCl
  • Spring Security Oauth2 认证(获取token/刷新token)流程(password模式)

    1 本文介绍的认证流程范围 本文主要对从用户发起获取token的请求 oauth token 到请求结束返回token中间经过的几个关键点进行说明 2 认证会用到的相关请求 注 所有请求均为post请求 获取access token请求 o