Spring Boot 通过AOP和自定义注解实现权限控制的方法
本文介绍了SpringBoot通过AOP和自定义注解实现权限控制,分享给大家,具体如下:
源码:https://github.com/yulc-coding/java-note/tree/master/aop
思路
- 自定义权限注解
- 在需要验证的接口上加上注解,并设置具体权限值
- 数据库权限表中加入对应接口需要的权限
- 用户登录时,获取当前用户的所有权限列表放入Redis缓存中
- 定义AOP,将切入点设置为自定义的权限
- AOP中获取接口注解的权限值,和Redis中的数据校验用户是否存在该权限,如果Redis中没有,则从数据库获取用户权限列表,再校验
pom文件引入AOP
org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-aop
自定义注解VisitPermission
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public@interfaceVisitPermission{ /** *用于配置具体接口的权限值 *在数据库中添加对应的记录 *用户登录时,将用户所有的权限列表放入redis中 *用户访问接口时,将对应接口的值和redis中的匹配看是否有访问权限 *用户退出登录时,清空redis中对应的权限缓存 */ Stringvalue()default""; }
需要设置权限的接口上加入注解@VisitPermission(value)
@RestController @RequestMapping("/permission") publicclassPermissionController{ /** *配置权限注解@VisitPermission("permission-test") *只用拥有该权限的用户才能访问,否则提示非法操作 */ @VisitPermission("permission-test") @GetMapping("/test") publicStringtest(){ System.out.println("==================step3:doing=================="); return"success"; } }
定义权限AOP
- 设置切入点为@annotation(VisitPermission)
- 获取请求中的token,校验是否token是否过期或合法
- 获取注解中的权限值,校验当前用户是否有访问权限
- MongoDB记录访问日志(IP、参数、接口、耗时等)
@Aspect @Component publicclassPermissionAspect{ /** *切入点 *切入点为包路径下的:execution(public*org.ylc.note.aop.controller..*(..)): *org.ylc.note.aop.Controller包下任意类任意返回值的public的方法 **切入点为注解的:@annotation(VisitPermission) *存在VisitPermission注解的方法 */ @Pointcut("@annotation(org.ylc.note.aop.annotation.VisitPermission)") privatevoidpermission(){ } /** *目标方法调用之前执行 */ @Before("permission()") publicvoiddoBefore(){ System.out.println("==================step2:before=================="); } /** *目标方法调用之后执行 */ @After("permission()") publicvoiddoAfter(){ System.out.println("==================step4:after=================="); } /** *环绕 *会将目标方法封装起来 *具体验证业务数据 */ @Around("permission()") publicObjectdoAround(ProceedingJoinPointproceedingJoinPoint)throwsThrowable{ System.out.println("==================step1:around=================="); longstartTime=System.currentTimeMillis(); /* *获取当前http请求中的token *解析token: *1、token是否存在 *2、token格式是否正确 *3、token是否已过期(解析信息或者redis中是否存在) **/ ServletRequestAttributesattributes=(ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); HttpServletRequestrequest=attributes.getRequest(); Stringtoken=request.getHeader("token"); if(StringUtils.isEmpty(token)){ thrownewRuntimeException("非法请求,无效token"); } //校验token的业务逻辑 //... /* *获取注解的值,并进行权限验证: *redis中是否存在对应的权限 *redis中没有则从数据库中获取权限 *数据空中没有,抛异常,非法请求,没有权限 **/ Methodmethod=((MethodSignature)proceedingJoinPoint.getSignature()).getMethod(); VisitPermissionvisitPermission=method.getAnnotation(VisitPermission.class); Stringvalue=visitPermission.value(); //校验权限的业务逻辑 //List
单元测试
packageorg.ylc.note.aop; importorg.junit.jupiter.api.BeforeEach; importorg.junit.jupiter.api.Test; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.boot.test.context.SpringBootTest; importorg.springframework.http.MediaType; importorg.springframework.test.web.servlet.MockMvc; importorg.springframework.test.web.servlet.MvcResult; importorg.springframework.test.web.servlet.request.MockMvcRequestBuilders; importorg.springframework.test.web.servlet.setup.MockMvcBuilders; importorg.ylc.note.aop.controller.PermissionController; @SpringBootTest classAopApplicationTests{ @Autowired privatePermissionControllerpermissionController; privateMockMvcmvc; @BeforeEach voidsetupMockMvc(){ mvc=MockMvcBuilders.standaloneSetup(permissionController).build(); } @Test voidapiTest()throwsException{ MvcResultresult=mvc.perform(MockMvcRequestBuilders.get("/permission/test") .accept(MediaType.APPLICATION_JSON) .header("token","9527")) .andReturn(); System.out.println("apitestresult:"+result.getResponse().getContentAsString()); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。