需求:
产品baba 说需要对部分方法进行白名单控制
设计:
1.新增一个白名单表,存储白名单;
2.然后新建一个白名单鉴权的切面;
3.需要鉴权的方法上直接使用自定义的鉴权注解。
实现:
1.建表
CREATE TABLE `t_white_list` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_name` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '用户名',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`is_delete` int(11) DEFAULT '0' COMMENT '删除标记 0 否 1 是',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='白名单表';
2.增删改查 方法(略.................)
3.切面注解@ScreenWhiteListAnnotation
/**
* @Description: 名单切面接口
* @author: luog
* @Date: 2021/3/22
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ScreenWhiteListAnnotation {
String module() default "";
}
4.切面实现
注意:
1.@Pointcut("@annotation(screenWhiteListAnnotation)") 就是定义 为使用 @ScreenWhiteListAnnotation 的方法才进切面
2.判断逻辑就是登陆用户名,不在白名单内,排除异常。
/**
* @Description: 白名单切面实现
* @author: luog
* @Date: 2021/3/22
*/
@Aspect
@Component
public class WhiteListAspect {
String methodName; // 方法名
private final Logger log = LoggerFactory.getLogger(ScreenWhiteListAspect.class);
@Resource
private ScreenWhiteListDao screenWhiteListDao;
/**
* 切入点
*/
@Pointcut("@annotation(screenWhiteListAnnotation)")
public void aopPointCut(ScreenWhiteListAnnotation screenWhiteListAnnotation) {
}
@Before("aopPointCut(screenWhiteListAnnotation)")
public void befor(JoinPoint joinPoint, ScreenWhiteListAnnotation screenWhiteListAnnotation) throws Exception {
methodName = joinPoint.getSignature().getDeclaringTypeName();
String currentUserName = UserUtil.getCurrentUser().getUsername();
List<ScreenWhiteList> screenWhiteList = screenWhiteListDao.listAll(new HashMap<>());
List<String> userNameList = screenWhiteList.stream().map(ScreenWhiteList::getUserName).collect(Collectors.toList());
if (!userNameList.contains(currentUserName)) {
log.error("【检查白名单】异常!");
log.error("用户:【" + currentUserName + "】不在白名单内!");
throw new UnauthorizedException("白名单授权异常!");
}else{
log.info("【检查白名单】正常。");
}
}
}
4.方法使用注解(@ScreenWhiteListAnnotation)
@PostMapping("/list")
@LogAnnotation
@ApiOperation(value = "列表")
@ScreenWhiteListAnnotation
public BaseResponseInfo<PageResponseInfo> list(@Valid @RequestBody DigitScreenReq request, HttpServletResponse response) {
Page<DigitScreenDTO> page = digitScreenService.selectPage(request);
return BaseResponseUtil.outputObject(page);
}
最终效果:
希望能帮到你!