概述
之前借助ai梳理了一篇《【十五】spring security oauth2 核心技术》博客,知识点介绍的还是很全面的,只是ai留有痕迹,文章发出反响不咋地,本次补充一篇实战心得,不在是简单的知识点堆积而是真实项目中的应用,有亮点也有槽点非常贴合大家实际研发面对的场景,接收的是别人的屎山代码,遇到bug要去阅读代码,想要重构没工期也没勇气,怕触发无限的bug。
应用场景
本篇先讲解一下spring security oauth2的真实应用,然后结合实际项目中又一个bug引发的一次深入学习的经历。
以下是按照spring security oauth2标准使用步骤罗列的,有些步骤没做实现就没有贴代码,一下都是项目中真实使用的代码:
实现步骤概览
第一阶段:基础配置
- 创建授权服务器 - 负责颁发令牌
- 创建资源服务器 - 负责验证令牌并保护API
- 配置用户详情服务 - 提供用户认证信息
- 配置客户端详情 - 管理OAuth2客户端应用
- 启用全局安全配置 - 基础安全设置
第二阶段:令牌与认证
-
配置JWT令牌服务 - 使令牌支持JWT格式
-
配置密码编码器 - 安全存储密码
-
创建用户实体与仓库 - 存储用户数据
创建授权服务器

核心代码不好贴出来,这里只讲解实现思路,这里主要是重写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规则,前人挖坑后人总是要填的,一般老系统积重难返了,也难怪很多时候后面的工程师只能沿着这条道往前走了。