源码地址:项目测试
视频讲解:基于SpringBoot的权限字符串和AOP注解拦截验证权限字符串以及布隆过滤器的使用问题_哔哩哔哩_bilibili
首先写注解
package com.fourthgroup.schoolmanagementsystem.annonation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface HasAuth {
String value() default "";
}
然后写权限AOP
package com.fourthgroup.schoolmanagementsystem.aop;
import com.fourthgroup.schoolmanagementsystem.annonation.HasAuth;
import com.fourthgroup.schoolmanagementsystem.common.constant.WebConstant;
import com.fourthgroup.schoolmanagementsystem.common.exception.BusinessException;
import com.fourthgroup.schoolmanagementsystem.entity.User;
import com.fourthgroup.schoolmanagementsystem.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Set;
@Slf4j
@Aspect
@Component
public class AuthorityAop {
@Autowired
private HttpServletRequest httpServletRequest;
@Autowired
private JwtUtil jwtUtil;
//定义切点,注解为切入点
@Pointcut("@annotation(com.fourthgroup.schoolmanagementsystem.annonation.HasAuth)")
public void AuthorityAopPointCut() {
}
@Before("AuthorityAopPointCut()")
public void before(JoinPoint joinPoint) throws Throwable {
log.info("进入Before通知...");
}
@After("AuthorityAopPointCut()")
public void after(JoinPoint joinPoint) throws Throwable {
log.info("进入After通知....");
}
@AfterReturning("AuthorityAopPointCut()")
public void afterReturning(JoinPoint joinPoint) throws Throwable {
log.info("进入AfterReturning通知....");
}
@AfterThrowing("AuthorityAopPointCut()")
public void afterThrowing(JoinPoint joinPoint) throws Throwable {
log.info("进入AfterThrowing通知....");
}
@Around("AuthorityAopPointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("进入controller==>Around通知....");
//从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//获取切入点所在的方法
Method method = signature.getMethod();
HasAuth viewRecords = method.getAnnotation(HasAuth.class);
String idValue = viewRecords.value();//user:add
log.info("SelfRecords====>idValue的值为:{}", idValue);
//获取到idValue值之后,我们获取user实体类里的这个menuUrlPathList
String token = httpServletRequest.getHeader(WebConstant.HEADER_TOKEN);
User user = jwtUtil.getUser(token);
// BloomFilter bloomFileter=user.getBloomFileter();
Set menuUrlPathList = user.getMenuUrlPathList();
if (!menuUrlPathList.contains(idValue)) {
throw new BusinessException("ForBidden 权限不足!");
}
return joinPoint.proceed();
}
}
然后在LoginController中加载数据库的权限字符串(这里我们直接写死,不从数据库中添加)
@Slf4j
@RestController
@RequestMapping("login")
public class LoginController {
@Autowired
private HttpServletRequest httpServletRequest;
@Autowired
private JwtUtil jwtUtil;
@Resource
private UserService userService;
@Resource
private StudentService studentService;
@Resource
private TeacherService teacherService;
@Resource
private LoginService loginService;
@Resource
private LogLoginService logLoginService;
@PostMapping("usernameLogin")
public void usernameLogin() {
User user=new User();
addAuth(user);
String token = jwtUtil.createToken(user);
user1.setToken(token);
}
public void addAuth(User user) {
//加权限字符串
Set menuUrlPathList = new HashSet<>();
menuUrlPathList.add("test");
user.setMenuUrlPathList(menuUrlPathList);
}
}
User类
package com.fourthgroup.schoolmanagementsystem.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fourthgroup.schoolmanagementsystem.util.BloomFilter;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
public class User implements Serializable {
private Long id;
private String username;
private String password;
private Integer state;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
@TableField(exist = false)
private Set menuUrlPathList;
@TableField(exist = false)
private Set menuUrlNameList;
@TableField(exist = false)
private String token;
@TableField(exist = false)
private String email;//以后修改邮箱的时候,更加方便,不用联表操作之类的
@TableField(exist = false)
private String phone;
@TableField(exist = false)
private List dutiesId;
@TableField(exist = false)
private List dutiesName;
@TableField(exist = false)
private BloomFilter bloomFileter;
}
测试
package com.fourthgroup.schoolmanagementsystem.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fourthgroup.schoolmanagementsystem.annonation.HasAuth;
import com.fourthgroup.schoolmanagementsystem.common.constant.NoticeConstant;
import com.fourthgroup.schoolmanagementsystem.common.constant.UserConstant;
import com.fourthgroup.schoolmanagementsystem.common.constant.WebConstant;
import com.fourthgroup.schoolmanagementsystem.common.web.PageWeb;
import com.fourthgroup.schoolmanagementsystem.common.web.ResultJson;
import com.fourthgroup.schoolmanagementsystem.entity.Notice;
import com.fourthgroup.schoolmanagementsystem.service.NoticeService;
import com.fourthgroup.schoolmanagementsystem.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@RestController
@RequestMapping("notice")
public class NoticeController {
@Autowired
private HttpServletRequest httpServletRequest;
@Autowired
private JwtUtil jwtUtil;
@Resource
private NoticeService noticeService;
@HasAuth("test")
@PostMapping("test")
public void test() {
System.out.println("test:::哈哈哈哈哈");
}
@HasAuth("test1")
@PostMapping("test1")
public void test1() {
System.out.println("test1::::哈哈哈哈哈");
}
}
此时我们可以访问HasAuth("test")中的方法,而HasAuth("test1")的方法不可访问,被AOP拦截住了