Spring Security与JWT集成实战:现代Java应用安全解决方案
1. Spring Security 核心价值与应用场景Spring Security 作为 Java 生态中最成熟的安全框架本质上解决的是谁能在什么条件下访问哪些资源的系统级安全问题。在前后端分离架构成为主流的今天传统基于 Session 的认证方式面临三大挑战跨域问题、无状态服务和移动端兼容性。我在金融、电商等多个行业的实践中发现JWTJSON Web Token与 Spring Security 的组合能完美适配现代架构需求。典型应用场景包括企业内部管理系统RBAC 权限控制电商平台OAuth2 社交登录IoT 设备接入证书Token 双认证开放平台API 访问鉴权注意选择 Spring Security 而非 Shiro 的核心考量是其与 Spring 生态的无缝集成特别是在微服务场景下对 OAuth2 和分布式会话的原生支持。2. 基础环境搭建与配置2.1 依赖配置关键点在 Spring Boot 2.7.x 项目中需要重点关注以下依赖项!-- 核心安全框架 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-security/artifactId /dependency !-- JWT支持 -- dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt-api/artifactId version0.11.5/version /dependency特别注意版本兼容性问题Spring Boot 2.7.x 对应 Spring Security 5.7.xJJWT 0.11.x 系列有完整的 API/Impl/Jackson 组件拆分2.2 安全配置类骨架基础配置类应继承WebSecurityConfigurerAdapterSpring Security 5.7 仍支持Configuration EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { Override protected void configure(HttpSecurity http) throws Exception { http .cors().and() .csrf().disable() .authorizeRequests() .antMatchers(/api/auth/**).permitAll() .anyRequest().authenticated() .and() .addFilter(new JwtAuthenticationFilter(authenticationManager())); } }踩坑记录Spring Security 5.4 版本中antMatchers()的路径匹配规则变得更严格/admin不会匹配/admin/建议始终使用统一的后缀斜杠。3. JWT 集成深度解析3.1 Token 生成与校验实现JWT 工具类应包含以下核心方法public class JwtUtils { private static final String SECRET_KEY your-256-bit-secret; private static final long EXPIRATION_MS 86400000; // 24小时 public static String generateToken(UserDetails userDetails) { return Jwts.builder() .setSubject(userDetails.getUsername()) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() EXPIRATION_MS)) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); } public static boolean validateToken(String token) { try { Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token); return true; } catch (Exception ex) { log.error(JWT validation error: {}, ex.getMessage()); return false; } } }密钥管理建议生产环境必须从配置中心或 KMS 获取密钥开发环境可使用分层加密环境变量 配置文件 默认值3.2 认证过滤器开发自定义过滤器需要继承OncePerRequestFilterpublic class JwtAuthenticationFilter extends OncePerRequestFilter { Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException { try { String token parseToken(request); if (token ! null JwtUtils.validateToken(token)) { Authentication auth createAuthentication(token); SecurityContextHolder.getContext().setAuthentication(auth); } filterChain.doFilter(request, response); } catch (Exception e) { response.sendError(HttpStatus.UNAUTHORIZED.value(), Invalid authentication); } } private Authentication createAuthentication(String token) { String username JwtUtils.getUsernameFromToken(token); UserDetails userDetails userDetailsService.loadUserByUsername(username); return new UsernamePasswordAuthenticationToken( userDetails, null, userDetails.getAuthorities()); } }性能优化点Token 校验过程中应缓存公钥/密钥避免每次请求都进行密钥解析。4. 前后端分离专项适配4.1 跨域解决方案推荐使用 Spring Security 原生 CORS 配置Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); CorsConfiguration config new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOriginPattern(*); config.addAllowedHeader(*); config.addAllowedMethod(*); source.registerCorsConfiguration(/**, config); return new CorsFilter(source); }常见问题排查预检请求OPTIONS被拦截确保antMatchers(HttpMethod.OPTIONS, /**).permitAll()带凭证的请求要求明确 Origin不能使用allowedOrigins(*)需改用allowedOriginPatterns4.2 响应格式统一处理自定义认证失败处理器Component public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException { response.setContentType(application/json;charsetUTF-8); response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.getWriter().write( JSON.toJSONString(Result.fail(401, Authentication failed)) ); } }在配置中注册http.exceptionHandling() .authenticationEntryPoint(jwtAuthenticationEntryPoint) .accessDeniedHandler(accessDeniedHandler);5. 权限控制进阶实现5.1 动态权限方案数据库驱动的权限模型实现public class DynamicPermissionEvaluator implements PermissionEvaluator { Override public boolean hasPermission(Authentication auth, Object targetDomainObject, Object permission) { String requiredPermission (String) permission; return auth.getAuthorities().stream() .anyMatch(grantedAuth - grantedAuth.getAuthority().equals(requiredPermission)); } }注册评估器Configuration public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { Override protected MethodSecurityExpressionHandler createExpressionHandler() { DefaultMethodSecurityExpressionHandler handler new DefaultMethodSecurityExpressionHandler(); handler.setPermissionEvaluator(new DynamicPermissionEvaluator()); return handler; } }5.2 方法级权限控制四种注解的实战用法PreAuthorize(hasRole(ADMIN)) // 角色校验 PreAuthorize(hasAuthority(user:add)) // 权限标识校验 PostAuthorize(returnObject.owner authentication.name) // 后置校验 Secured({ROLE_OPERATOR, ROLE_ADMIN}) // 简单角色校验开发技巧在开发环境开启EnableGlobalMethodSecurity(prePostEnabled true, securedEnabled true)的调试日志可输出详细的权限决策过程。6. 生产级安全加固6.1 防攻击策略关键安全头配置示例http.headers() .contentSecurityPolicy(default-src self) .and() .referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN) .and() .httpStrictTransportSecurity() .includeSubDomains(true) .maxAgeInSeconds(31536000);6.2 会话管理无状态会话配置http.sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS);并发控制策略适用于混合认证系统http.sessionManagement() .maximumSessions(1) .expiredSessionStrategy(new CustomSessionExpiredStrategy());7. 测试与调试技巧7.1 单元测试方案安全上下文注入测试SpringBootTest AutoConfigureMockMvc public class SecurityTest { Test WithMockUser(usernameadmin, roles{ADMIN}) public void testAdminEndpoint() throws Exception { mockMvc.perform(get(/api/admin)) .andExpect(status().isOk()); } }7.2 实时调试工具推荐组合使用Spring Security Debug FilterEnableWebSecurity(debug true)Actuator 的/actuator/health端点浏览器开发者工具的 Network 和 Application 面板8. 性能优化实践8.1 密码加密选型现代密码哈希方案对比算法强度适用场景Spring Security 支持bcrypt高常规用户密码PasswordEncoderFactories.createDelegatingPasswordEncoder()Argon2极高高安全要求系统需额外依赖 spring-security-cryptoPBKDF2中合规性要求场景内置支持8.2 缓存策略用户信息缓存实现Cacheable(value userDetails, key #username) public UserDetails loadUserByUsername(String username) { // 数据库查询逻辑 }缓存失效策略建议权限变更时清除对应用户缓存设置合理的 TTL建议 30-60 分钟9. 常见问题解决方案9.1 认证循环问题现象不断重定向到登录页 解决方案检查清单确保放行了登录接口/login检查 CSRF 配置是否与前端一致验证成功处理器是否正确返回 JSON9.2 跨域 Cookie 失效关键配置项response.setHeader(Access-Control-Allow-Credentials, true); Cookie cookie new Cookie(token, token); cookie.setHttpOnly(true); cookie.setPath(/); cookie.setDomain(.yourdomain.com); // 注意前导点号 cookie.setSecure(true); // HTTPS必须10. 扩展功能集成10.1 OAuth2 社交登录微信登录配置示例Bean public ClientRegistration wechatClientRegistration() { return CommonOAuth2Provider .custom() .clientId(wechat-appid) .clientSecret(wechat-secret) .authorizationUri(https://open.weixin.qq.com/connect/qrconnect) .tokenUri(https://api.weixin.qq.com/sns/oauth2/access_token) .userInfoUri(https://api.weixin.qq.com/sns/userinfo) .clientName(WeChat) .build(); }10.2 二次认证方案短信验证码认证流程实现AuthenticationProvider接口在认证过滤器中添加额外校验使用 Redis 存储临时验证码public class SmsCodeAuthenticationProvider implements AuthenticationProvider { Override public Authentication authenticate(Authentication auth) { String mobile (String) auth.getPrincipal(); String code (String) auth.getCredentials(); if (!verifyCode(mobile, code)) { throw new BadCredentialsException(Invalid verification code); } UserDetails user userDetailsService.loadUserByUsername(mobile); return new UsernamePasswordAuthenticationToken( user, null, user.getAuthorities()); } }在实际项目中Spring Security 的深度定制需要平衡安全性和开发效率。建议从最小化安全配置开始逐步添加功能模块每个阶段都进行完整的安全测试。对于关键业务系统应当考虑引入专业的安全审计工具如 OWASP ZAP 进行渗透测试。

相关新闻

全面解析最新4K60无线HDMI视频传输方案功能规格

全面解析最新4K60无线HDMI视频传输方案功能规格

最新4K60无线视频传输方案功能规格全面解析-AM8960/AM8860一、方案定位:替代线缆的 4K60 无线显示链路二、Compact Air 三档方案矩阵三、系统组成与信号链路四、核心规格总览五、视频能力与低延迟表现六、DisplayPass 技术架构七、产品功能清单八、硬件接口与按键交…

2026/10/15 3:42:42 阅读更多 →
RGF 仓颉版 TextFormat 文本格式类完全指南:字体属性、段落排版与行裁剪配置

RGF 仓颉版 TextFormat 文本格式类完全指南:字体属性、段落排版与行裁剪配置

图形学桌面应用 【免费下载链接】RGF_CJ RGF是仓颉Windows系统下的通用渲染框架(兼应用开发框架)。RGF仓颉版(后续简称"RGF")基于RGF(C/C版)封装优化而来。RGF为开发者提供轻量化、安全、高性能以及高度一致性的2D渲染能…

2026/10/15 3:42:42 阅读更多 →
TypeScript 实现 SRT 和 WebVTT 字幕导出:时间戳格式化与双语 SRT

TypeScript 实现 SRT 和 WebVTT 字幕导出:时间戳格式化与双语 SRT

本文使用 TypeScript 和 Node.js,将带毫秒时间戳的转写片段导出为原文 SRT、原文 WebVTT 与双语 SRT。核心流程是校验源数据、格式化时间、按索引匹配译文,再按源顺序生成字幕块。 工程背景来自 Vimorph 的转写与字幕模块。示例独立运行,使用…

2026/10/15 3:42:42 阅读更多 →

最新新闻

测试用例编写指南:构建可验证、可追溯、可对齐的用例生成机制

测试用例编写指南:构建可验证、可追溯、可对齐的用例生成机制

简介:本资源是一份面向软件测试工程师及初级测试人员的《测试用例编写指南》实战文档,聚焦解决测试设计逻辑不统一、用例颗粒度不一致、异常场景覆盖不足等常见痛点。文档系统梳理了从需求分析、业务流程拆解、系统设计映射到用例编写与维护的全流程步骤…

2026/10/15 4:33:51 阅读更多 →
Win11控制面板入口太深?教你固定到开始菜单

Win11控制面板入口太深?教你固定到开始菜单

Win11这代系统,把开始菜单改成了居中式卡片布局,一眼看上去确实清爽利落。但很多从Win10时代用过来的老用户,第一次打开Win11都会愣一下:控制面板哪去了?其实控制面板并没有被删除,它只是被“藏”起来了——…

2026/10/15 4:33:51 阅读更多 →
Spring Boot大型超市前后台系统:从业务建模到库存防超卖实战

Spring Boot大型超市前后台系统:从业务建模到库存防超卖实战

做后台管理系统这件事,在Java技术圈里一直有两种声音:一种觉得就是“增删改查”的堆砌,没什么技术含量;另一种觉得真正能把复杂业务捋清楚、把性能和数据一致性做到位,非常考验功底。我属于后者,尤其是当你…

2026/10/15 4:33:51 阅读更多 →
Python语法实战备忘录:68页可验证、可测试、可避坑的工程化指南

Python语法实战备忘录:68页可验证、可测试、可避坑的工程化指南

简介:这是一份面向Python初学者及转语言开发者的系统性语法入门手册,聚焦零基础快速构建核心编程能力,解决语法概念模糊、示例缺失、实践脱节等常见学习痛点。资源为单文件PDF,共68页、1.42MB,内容覆盖变量与数据类型&…

2026/10/15 4:33:51 阅读更多 →
AI视频时长提升至10分钟以上;OpenAI员工涉偷装录音设备被捕 | 科技日报1014

AI视频时长提升至10分钟以上;OpenAI员工涉偷装录音设备被捕 | 科技日报1014

AI视频时长提升至10分钟以上 #1Higgsfield借助 GPT-6 Astra,把 AI 视频的时长从 1 分钟延长到 10 分钟以上。 该公司同时使用 GPT-Image-2.5 提供更精确的画面,并通过 GPT-Live 为语音电影制作提供一条路径。 OpenAI员工涉偷装录音设备被捕 #2OpenAI表示…

2026/10/15 4:33:51 阅读更多 →
STM32F407 FSMC驱动LCD实战:从寄存器到LVGL与DMA优化

STM32F407 FSMC驱动LCD实战:从寄存器到LVGL与DMA优化

简介:这份资源面向嵌入式开发初学者与进阶工程师,提供基于STM32F407与FSMC接口驱动LCD液晶屏的完整工程方案,解决图形界面开发中屏幕刷新慢、字符与汉字显示难、图形绘制繁琐等问题。压缩包共91个文件,以41个C源文件与37个头文件为…

2026/10/15 4:32:51 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →