Spring Boot中JWT权限验证需配置jjwt依赖(0.12.5)、JwtProperties、JwtUtil工具类(含token生成/解析/校验)、继承OncePerRequestFilter的认证过滤器(须在UsernamePasswordAuthenticationFilter前注册),并启用@EnableGlobalMethodSecurity(prePostEnabled = true)配合@PreAuthorize实现方法级权限控制。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

在Spring Boot项目中快速实现JWT权限验证逻辑,需要让通义灵码准确理解认证流程、Token生成与校验边界、以及拦截器与注解的配合方式。
准备JWT依赖与配置类
在pom.xml中添加jjwt-api、jjwt-impl、jjwt-jackson依赖,版本统一为0.12.5;旧版0.11.x存在Jackson反序列化漏洞,【必须升级】。
新建JwtProperties配置类,用@ConfigurationProperties(prefix = "jwt")绑定yml中的密钥、过期时间、签发者等字段,注意密钥长度不能低于256位,否则HS256算法会抛IllegalArgumentException。
在application.yml中写入jwt.secret: "your-32-byte-secret-key-here-123456789012",密钥必须是BASE64编码字符串或原始字节数组长度32,硬编码仅用于本地调试,生产环境务必改用环境变量注入。
定义JWT工具类生成与解析Token
创建JwtUtil工具类,提供generateToken(UserDetails user)方法:用Jwts.builder()设置subject(用户ID)、claims(角色列表)、过期时间(exp)、签发时间(iat)和签发者(iss),最后用HmacSHA256签名。
提供getUsernameFromToken(String token)方法:先去掉Bearer前缀,再用Jwts.parserBuilder().setSigningKey(jwtProperties.getSecret()).build()解析,捕获ExpiredJwtException、UnsupportedJwtException等异常并返回null——这是关键容错点,避免未授权请求直接崩掉过滤器链。
提供validateToken(String token, UserDetails userDetails)方法:校验token是否未过期、用户名是否匹配、签名是否有效。注意这里不校验角色,角色校验应由@PreAuthorize在Controller层完成,否则会导致权限变更延迟生效。
编写JWT认证过滤器
继承OncePerRequestFilter,重写doFilterInternal方法。
通义灵码 Linux版是阿里云推出的一款AI智能编码助手,专为Linux开发者设计。它支持在Linux操作系统下的JetBrains IDEs、Visual Studio Code等主流集成开发环境中运行。该工具基于通义大模型,提供代码智能生成、实时续写、单元测试生成、代码优化以及研发智能问答等功能,旨在帮助Linux用户在编码过程中提升效率。
第一步:从HttpServletRequest的Authorization头中提取token,格式为“Bearer
第二步:调用JwtUtil.getUsernameFromToken(token),若返回null,说明token无效,构造Response返回401状态码并中断流程;若非空,则查UserDetailsService加载用户完整信息。
第三步:将用户信息封装为UsernamePasswordAuthenticationToken,设置到SecurityContextHolder.getContext().setAuthentication(authentication),这一步完成后,@PreAuthorize注解才能正确读取当前用户角色。
注意:该过滤器必须在UsernamePasswordAuthenticationFilter之前注册,否则登录成功后无法及时注入认证上下文。
启用方法级权限控制
在启动类上添加@EnableGlobalMethodSecurity(prePostEnabled = true)注解,开启@PreAuthorize支持。
方法一:在Controller方法上加@PreAuthorize("hasRole('ADMIN')"),表示仅ADMIN角色可访问;角色名需与UserDetails.getAuthorities()返回的GrantedAuthority.getAuthority()值完全一致,通常为"ROLE_ADMIN"而非"ADMIN",【若数据库存的是ADMIN,需在UserDetails实现中手动拼接"ROLE_"前缀】。
方法二:使用表达式@PreAuthorize("hasAnyRole('ADMIN','USER') or #id == authentication.principal.id"),支持复杂逻辑,其中#id是方法参数名,authentication是SecurityContext中自动注入的对象。
方法三:对整个Controller类加@RestControllerAdvice + @ExceptionHandler(JwtException.class),统一返回JSON格式错误响应,避免默认的白页报错暴露堆栈。


















