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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。