了解 JWT 身份验证:Spring Security 的架构和 Go 实现
一分耕耘,一分收获!既然打开了这篇文章《了解 JWT 身份验证:Spring Security 的架构和 Go 实现》,就坚持看下去吧!文中内容包含等等知识点...希望你能在阅读本文后,能真真实实学到知识或者帮你解决心中的疑惑,也欢迎大佬或者新人朋友们多留言评论,多给建议!谢谢!
设置 JWT 无状态身份验证(可在此处获取)后,我想通过识别关键组件及其交互来了解 Spring Security 抽象下发生的情况。为了让这种探索更有吸引力,我使用标准 HTTP 库在 Go 中重新实现了一个最小版本。通过分解三个核心流程 - 注册、令牌生成和受保护的资源访问 - 并在 Go 中重建它们,我开始将 Spring Security 的身份验证模式映射到更简单的组件。
这篇文章特别关注身份验证流程 - 系统如何验证用户身份 - 而不是授权。我们将使用序列图探索流程,这些序列图通过 Spring Security 架构中的不同组件跟踪请求。
主要部件
系统提供三个端点:
- 用户注册:接受新用户的用户名和密码
- 令牌生成(登录):当用户使用有效凭据成功登录时创建 JWT 令牌
- 受保护的访问:使经过身份验证的用户能够使用其令牌访问受保护的资源。 getAuthenticatedUser 端点作为示例,返回经过身份验证的令牌持有者的个人资料信息
在以下部分中,我将解释每个流程中涉及的核心组件,并为每个流程提供序列图。
注册流程
包含用户名和密码的注册请求通过 Spring Security 过滤器链,由于注册端点被配置为不需要在 SecurityConfiguration 中进行身份验证,因此在该过滤器链中进行的处理最少。然后请求通过 Spring 的 DispatcherServlet,后者根据 URL 模式将其路由到 UserController 中的适当方法。请求到达 UserController 的注册端点,其中用户信息与散列密码一起存储。
代币生成流程
包含用户名和密码的登录请求通过 Spring Security 过滤器链,其中发生最少的处理,因为此端点也配置为不需要在 SecurityConfiguration 中进行身份验证。请求通过 Spring 的 DispatcherServlet 移动到 UserController 的登录端点,该端点委托给 AuthenticationManager。使用 ApplicationConfiguration 中定义的配置 bean,AuthenticationManager 根据存储的凭据验证提供的凭据。身份验证成功后,UserController 使用 JwtService 生成包含用户信息和创建时间等元数据的 JWT 令牌,该令牌将返回给客户端以供后续经过身份验证的请求。
受保护的资源访问流程
成功的身份验证流程 (200)
身份验证流程失败 (401)
当授权标头中包含 JWT 令牌的请求到达时,它会通过 JwtAuthenticationFilter - 自定义定义的 OncePerRequestFilter - 它使用 JwtService 处理令牌。如果有效,过滤器将通过 ApplicationConfiguration 中配置的 UserDetailsService 检索用户,并在 SecurityContextHolder 中设置身份验证。如果令牌丢失或无效,过滤器将允许请求继续,而无需设置身份验证。
在链的后面,AuthorizationFilter 检查请求是否通过 SecurityContextHolder 进行了正确的身份验证。当它检测到缺少身份验证时,它会抛出 AccessDeniedException。此异常由 ExceptionTranslationFilter 捕获,它检查用户是否是匿名的,并委托给 SecurityConfiguration 中配置的 JwtAuthenticationEntryPoint 返回 401 Unauthorized 响应。
如果所有过滤器都通过,请求将到达 Spring 的 DispatcherServlet,后者将其路由到 UserController 中的 getAuthenticatedUser 端点。此端点从过滤器链过程中填充的 SecurityContextHolder 检索经过身份验证的用户信息。
注意:Spring Security 采用丰富的过滤器和专用组件生态系统来处理各种安全问题。为了理解核心身份验证流程,我只关注 JWT 令牌验证和用户身份验证中的关键参与者。
Go 实现:映射组件
Go 实现通过映射到关键 Spring Security 组件的简化架构提供类似的功能:
过滤链
- 提供 Spring Security 过滤器链的最小版本
- 按顺序处理每个请求的过滤器
- 使用每个请求链实例(VirtualFilterChain)来实现线程安全
调度员
- 映射到 Spring 的 DispatcherServlet
- 安全过滤器处理后将请求路由到适当的处理程序
身份验证上下文
- 使用Go的上下文包来存储每个请求的身份验证状态
- 映射到 Spring 的 SecurityContextHolder
JwtFilter
- 直接相当于Spring的JwtAuthenticationFilter
- 提取并验证 JWT 令牌
- 成功验证后填充身份验证上下文
身份验证过滤器
- Spring的AuthorizationFilter的简化版
- 专注于身份验证
- 检查身份验证上下文,如果缺失则返回 401
JwtService
- 类似于Spring的JwtService
- 处理令牌生成和验证
- 使用相同的核心 JWT 操作,但配置更简单
测试覆盖率
两种实现都包括验证密钥身份验证场景的集成测试(auth_test.go 和 AuthTest.java):
报名流程
- 使用有效凭据成功用户注册
- 重复的用户名注册尝试
登录流程
- 使用有效凭据成功登录
- 尝试使用不存在的用户名登录
- 尝试使用错误密码登录
受保护的资源访问
- 使用有效令牌成功访问
- 没有 auth header 的访问尝试
- 尝试使用无效令牌格式进行访问
- 使用过期令牌进行访问
- 尝试使用有效的令牌格式进行访问,但用户不存在
Java 实现包括详细注释,通过 Spring Security 的过滤器链解释每个测试场景的流程。使用等效组件在 Go 实现中复制这些相同的流程。
旅程总结
我通过将 Spring Security 的 JWT 身份验证分解为流程和测试用例来研究它。然后我将这些模式映射到 Go 组件。集成测试向我展示了请求如何流经 Spring Security 的过滤器链和组件。构建这些模式的简单版本帮助我理解了 Spring Security 的设计。测试证明两种实现都以相同的方式处理身份验证。通过分析、测试和重建,我对 Spring Security 的身份验证工作原理有了更深入的了解。
到这里,我们也就讲完了《了解 JWT 身份验证:Spring Security 的架构和 Go 实现》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!

- 上一篇
- linux framebuffer双缓冲怎样优化

- 下一篇
- SpringBoot线上教育应用如何有效保护核心代码,防止商业权益受损?
-
- Golang · Go教程 | 6小时前 |
- Debian实战:手把手教你Swagger+k8s集成超简单教程
- 232浏览 收藏
-
- Golang · Go教程 | 7小时前 |
- Debian手把手教学!Tomcat配置+安全性优化教程
- 454浏览 收藏
-
- Golang · Go教程 | 7小时前 | 内存泄漏 prometheus pprof gRPC双向流 Context管理
- Go程序用gRPC双向流出现内存泄漏?手把手教你定位解决!
- 284浏览 收藏
-
- Golang · Go教程 | 8小时前 |
- Debian装Hadoop存储不够?手把手教你轻松扩容
- 243浏览 收藏
-
- Golang · Go教程 | 9小时前 | Http请求 RESTfulAPI GolangHTTP编程 net/http包 Handler接口
- 手把手教你用Golang玩转HTTP请求|GolangHTTP编程超简单教程
- 168浏览 收藏
-
- Golang · Go教程 | 9小时前 |
- Debian系统配置phpstorm自动备份教程
- 243浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 茅茅虫AIGC检测
- 茅茅虫AIGC检测,湖南茅茅虫科技有限公司倾力打造,运用NLP技术精准识别AI生成文本,提供论文、专著等学术文本的AIGC检测服务。支持多种格式,生成可视化报告,保障您的学术诚信和内容质量。
- 62次使用
-
- 赛林匹克平台(Challympics)
- 探索赛林匹克平台Challympics,一个聚焦人工智能、算力算法、量子计算等前沿技术的赛事聚合平台。连接产学研用,助力科技创新与产业升级。
- 84次使用
-
- 笔格AIPPT
- SEO 笔格AIPPT是135编辑器推出的AI智能PPT制作平台,依托DeepSeek大模型,实现智能大纲生成、一键PPT生成、AI文字优化、图像生成等功能。免费试用,提升PPT制作效率,适用于商务演示、教育培训等多种场景。
- 90次使用
-
- 稿定PPT
- 告别PPT制作难题!稿定PPT提供海量模板、AI智能生成、在线协作,助您轻松制作专业演示文稿。职场办公、教育学习、企业服务全覆盖,降本增效,释放创意!
- 83次使用
-
- Suno苏诺中文版
- 探索Suno苏诺中文版,一款颠覆传统音乐创作的AI平台。无需专业技能,轻松创作个性化音乐。智能词曲生成、风格迁移、海量音效,释放您的音乐灵感!
- 85次使用
-
- Golangmap实践及实现原理解析
- 2022-12-28 505浏览
-
- 试了下Golang实现try catch的方法
- 2022-12-27 502浏览
-
- Go语言中Slice常见陷阱与避免方法详解
- 2023-02-25 501浏览
-
- Golang中for循环遍历避坑指南
- 2023-05-12 501浏览
-
- Go语言中的RPC框架原理与应用
- 2023-06-01 501浏览