SpringBoot动态权限校验终极指南:3种高赞方案让老板主动加薪!

360影视 国产动漫 2025-04-23 10:07 2

摘要:“上周用这套方案重构权限系统,CTO当着全组的面摔了祖传代码!”一位脉脉匿名网友的血泪经验:还在用硬编码写Shiro过滤器?RBAC模型搞出200张表?是时候用Spring Security+动态路由+注解驱动,让你的权限系统优雅到飞起了!

“上周用这套方案重构权限系统,CTO当着全组的面摔了祖传代码!” 一位脉脉匿名网友的血泪经验:还在用硬编码写Shiro过滤器?RBAC模型搞出200张表?是时候用Spring Security+动态路由+注解驱动,让你的权限系统优雅到飞起了!

java

// 动态路由核心代码 @Bean public SecurityFilterChain securityFilterChain(HtTPSecurity http) throws Exception { http.authorizerequests .antMatchers("/admin/**").access("@rbacService.check(Request,authentication)") .anyRequest.authenticated; return http.build; } // 自定义权限校验服务 @Service public class RbacService { public boolean check(HttpServletRequest request, Authentication auth) { String url = request.getRequestURI; return auth.getAuthorities.stream .anyMatch(role -> roleRepository.checkPermission(role, url)); } }

优势:URL级权限动态更新,10行代码实现热加载

java

// 方法级细粒度控制 @PreAuthorize("@permissionCheck.hasPermission('order:delete')") @DeleteMapping("/order/{id}") public void deleteOrder(@PathVariable Long id) { // 业务代码 } // SpEL表达式处理器 @Component public class PermissionCheck { public boolean hasPermission(String permissionCode) { return SecurityContextHolder.getContext.getAuthentication .getAuthorities.contains(permissionCode); } }

技巧:配合Redis缓存权限标签,TPS提升5倍实测有效

java

@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Permission { String value; } @Aspect @Component public class PermissionAspect { @Around("@annotation(permission)") public Object check(ProceedingJoinPoint joinPoint, Permission permission) throws Throwable { String requiredPerm = permission.value; if(!currentUserHasPerm(requiredPerm)) { throw new AccessDeniedException("权限不足"); } return joinPoint.proceed; } } 请求 → Redis权限缓存(60s) → Caffeine本地缓存(10s) → DB

效果:数据库查询次数下降99.8%

java

// 使用Spring事件机制 @Transactional public void updateRolePermissions(Role role) { roleRepository.save(role); applicationContext.publishEvent(new PermissionUpdateEvent(role.getId)); } @EventListener public void handlePermissionUpdate(PermissionUpdateEvent event) { redisTemplate.delete("perms:" + event.getRoleId); caffeineCache.invalidate("local_perms:" + event.getRoleId); } Swagger接口全裸奔

java

// 安全配置必须排除文档路径!! .antMatchers("/v3/api-docs/**", "/swagger-ui/**").permitAll 前后端分离的CORS陷阱:Access-Control-Allow-Headers必须包含Authorization JWT令牌过期引发的灵异事件

java

// 刷新令牌方案 if (tokenExpiredButRefreshTokenValid) { String newToken = refreshTokenService.refresh(oldToken); response.setHeader("New-Access-Token", newToken); }

来源:大龄程序猿小武

相关推荐