【十六】记录Spring Security OAuth2的实战经验

概述

之前借助ai梳理了一篇《【十五】spring security oauth2 核心技术》博客,知识点介绍的还是很全面的,只是ai留有痕迹,文章发出反响不咋地,本次补充一篇实战心得,不在是简单的知识点堆积而是真实项目中的应用,有亮点也有槽点非常贴合大家实际研发面对的场景,接收的是别人的屎山代码,遇到bug要去阅读代码,想要重构没工期也没勇气,怕触发无限的bug。

应用场景

本篇先讲解一下spring security oauth2的真实应用,然后结合实际项目中又一个bug引发的一次深入学习的经历。

以下是按照spring security oauth2标准使用步骤罗列的,有些步骤没做实现就没有贴代码,一下都是项目中真实使用的代码:

实现步骤概览

第一阶段:基础配置

  1. 创建授权服务器 - 负责颁发令牌
  2. 创建资源服务器 - 负责验证令牌并保护API
  3. 配置用户详情服务 - 提供用户认证信息
  4. 配置客户端详情 - 管理OAuth2客户端应用
  5. 启用全局安全配置 - 基础安全设置

第二阶段:令牌与认证

  1. 配置JWT令牌服务 - 使令牌支持JWT格式

  2. 配置密码编码器 - 安全存储密码

  3. 创建用户实体与仓库 - 存储用户数据

创建授权服务器

核心代码不好贴出来,这里只讲解实现思路,这里主要是重写configure方法,主要用来配置客户端信息存储方式、授权类型、刷新令牌配置等。

创建资源服务器


负责验证令牌并保护API资源,这里我们注意一下有一下几种权限配置:

一般我们用到的是permitAll,在上面configure走配置的就是这个允许所有用户访问,无需任何省份验证,很多接口就是不需要鉴权的,比如登入登出等。

配置用户详情服务

这里主要重写了loadUserByUsername方法,在这个方法里我们可以做加解密、验证令牌合法性等,还有各系统自身特色的功能,比如我们系统需要验证租户信息以及各种角色信息。

启用全局安全配置

这里配置了禁用CRSF、禁用基本认证,另外还可以配置密码编码器。

以上就是正常的使用步骤,然而微服务经过不同人参与,我们系统出现了两套token生成校验规则,于是引发了一个问题,一队人使用hutool工具包实现了一套token生成规则,而系统现在有一个场景需要刷新token,这时候刷新token又是调用的spring security oauth2的refresh_token,这个问题给我一顿好找啊!

一开始我想到的是通过其他模式去获取refresh_token给用户刷新token使用,OAuth2有四种模式:
// 1. 授权码模式 (Authorization Code) - 最安全

// 适用于 Web 应用,有后端服务

// 流程:客户端 → 授权页面 → 授权码 → 令牌

// 2. 简化模式 (Implicit) - 简化但安全性较低

// 适用于纯前端 SPA 应用

// 流程:客户端 → 授权页面 → 令牌(直接在URL中返回)

// 3. 密码模式 (Resource Owner Password Credentials)

// 适用于高度信任的客户端(如自家移动App)

// 流程:客户端用 用户名/密码 → 直接获取令牌

// 4. 客户端模式 (Client Credentials)

// 适用于机器对机器通信

// 流程:客户端凭据 → 获取令牌

最先我想到了使用密码模式去获取token,于是实现了如下API:

这里发现系统密码是前端把明文密码先通过md5加密,之后再通过国密SM2通过公钥加密传输到后端的,后端则是国密解密之后通过单向哈希算法加密的,这样一来,后端是无法反解密码的。

后面我又尝试了客户端认证的模式,但是这个模式获取的token不带用户信息,无法用来作为刷新token使用。

总结

本文结合实际场景介绍了Spring Security OAuth2的使用以及真实使用场景,一般来讲我们正常使用Spring Security 认证逻辑是很清晰的,给相关接口开通鉴权,做好密码加解密,设置token过期时间,调用刷新token接口更新,但是实际场景突发状况无法预料,就像我这套系统有两个token规则,前人挖坑后人总是要填的,一般老系统积重难返了,也难怪很多时候后面的工程师只能沿着这条道往前走了。

相关推荐
长不大的杨瑞杰11 分钟前
OpenCode v2 LSP 实战:内置语言服务器、自定义配置与诊断闭环
java·人工智能·typescript·lsp·opencode
云和数据.ChenGuang16 分钟前
python和java的try
java·开发语言·python
日日大王学编程17 分钟前
阿里巴巴开源 Data Agent(Text2SQL)项目全维度详解
java·ai·开源
Wang's Blog20 分钟前
Java 项目实战:交友项目 - 交友左滑右滑
java·交友
环境栈笔记23 分钟前
指纹浏览器安卓怎么用?从运行位置到功能验收,先把三种方案分清
前端·人工智能·后端·自动化
测试盐23 分钟前
spark作业日志定位过程
java·hadoop·spark
ly768927 分钟前
从 OpenAPI 到多语言 SDK 生成:Java 服务端契约漂移与生成器版本治理
java·开发语言·openapi·java 21·版本兼容·契约漂移·sdk 生成
lqbzlll40 分钟前
CVE-2026-91403 排查指南:Java JSSE 信任链漏洞的根因、影响范围和修复步骤
java·开发语言·信任链
CarIise43 分钟前
AOP 概念的引入
java·开发语言
小小张说故事1 小时前
Python 的 list 为什么能装下任何类型?拆开 PyObject* 数组,以及它让你多付了多少内存
后端·python