1.生成注解
package cn.wanda.common.annotation;
import cn.wanda.common.typeenum.DataScopeEnum;
import cn.wanda.common.typeenum.UserAuthEnum;
import java.lang.annotation.*;
/**
* 用户功能权限过滤注解
*
* @author : WangYuanYi
* @description :
* @create :2021-11-17 15:47:00
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface UserAuth {
String systemCode() default "";
UserAuthEnum dealType() default UserAuthEnum.TOKEN;
}
2.核心代码
package cn.wanda.common.aspect;
import cn.wanda.common.annotation.UserAuth;
import cn.wanda.common.base.PerAuthorityEntity;
import cn.wanda.common.base.UserAuthEntity;
import cn.wanda.common.typeenum.UserAuthEnum;
import cn.wanda.common.utils.R;
import cn.wanda.common.utils.RedisUtils;
import cn.wanda.modules.sso.service.impl.AuthService;
import cn.wanda.modules.sso.utils.AuthConstant;
import cn.wanda.modules.sys.dao.SysMenuDao;
import cn.wanda.modules.sys.entity.SysMenuEntity;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import net.bytebuddy.implementation.bytecode.Throw;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.dozer.DozerBeanMapper;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.*;
/**
* 用户功能权限处理
*
* @author : WangYuanYi
* @description :
* @create :2021-11-17 15:45:00
*/
@Aspect
@Component
@AllArgsConstructor
public class UserAuthAspect {
private AuthService authService;
private SysMenuDao sysMenuDao;
private RedisUtils redisUtils;
private static AuthService staticAuthService;
private static SysMenuDao staticSysMenuDao;
private static RedisUtils staticRedisUtils;
/**
* 第一步:写注解@Component 使当前类成为一个bean对象。(@Controller,@service都行)
* 第二步:写个static的变量
* 第三步:写个@PostConstruct注解注解注释的方法,在这个方法里,将自动注入的值赋值给定义的static变量
* 第四步:static变量替代自动注入在static方法里面使用
*
* @PostConstruct注解作用:是Java EE 5引入的注解,Spring允许开发者在受管Bean中使用它。当
* DI容器实例化当前受管Bean时,@PostConstruct注解的方法会被自动触发,从而完成一些初始化工
* 作。
*/
@PostConstruct
public void init() {
staticAuthService = authService;
staticSysMenuDao = sysMenuDao;
staticRedisUtils = redisUtils;
}
// 配置织入点
@Pointcut("@annotation(cn.wanda.common.annotation.UserAuth)")
public void UserAuthPointCut() {
}
@Before("UserAuthPointCut()")
public void doBefore(JoinPoint point) throws Throwable {
handleUserAuth(point);
}
protected void handleUserAuth(final JoinPoint joinPoint) throws Exception {
// 获得注解
UserAuth controllerUserAuth = getAnnotationLog(joinPoint);
if (controllerUserAuth == null) {
return;
}
UserAuthFilter(joinPoint, controllerUserAuth);
// 获取当前的用户
// LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest());
// if (StringUtils.isNotNull(loginUser))
// {
// SysUser currentUser = loginUser.getUser();
// // 如果是超级管理员,则不过滤数据
// if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin())
// {
// UserAuthFilter(joinPoint, currentUser, controllerUserAuth.deptAlias(),
// controllerUserAuth.userAlias());
// }
// }
}
/**
* 数据范围过滤 在此方法中编写
*
* @param joinPoint 切点
*/
public static void UserAuthFilter(JoinPoint joinPoint, UserAuth controllerUserAuth) throws Exception {
String systemCode = controllerUserAuth.systemCode();
HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
// 获取token
String token = request.getHeader("token");
// 解析token
Map<Object, Object> userInfo = staticAuthService.getUserInfo(token);
Map<Object, Object> object1 = (HashMap<Object, Object>) userInfo.get("userinfo");
String user = (String) object1.get("username");
// 获取功能权限接口需要提供的参数
Map<String, String> param = new HashMap<>();
// 暂定写死 完善真实数据后 改为动态 systemName: 系统编码 userName 用户名
param.put("systemId", "123");
param.put("userName", "admin123");
// 获取路径
String authUrl = "http://" + AuthConstant.AUTH_USER_DATA_AUTHORITY;
// 获取功能权限接口
String s = staticAuthService.doGet(authUrl, param);
// 获取权限code码
Map map = JSON.parseObject(s, Map.class);
String ss1 = map.get("data").toString();
Map map1 = null;
if (ss1.length() > 4) {
map1 = JSON.parseObject(ss1, Map.class);
} else {
throw new Exception("该用户暂无功能权限,参数:" + ss1);
}
// Map map1 = JSON.parseObject(ss1, Map.class);
List<PerAuthorityEntity> data = mapList((Collection) map1.get("allAuthList"), PerAuthorityEntity.class);
HashSet<String> hashSet = new HashSet<>();
HashSet<String> hashSet1 = new HashSet<>();
for (PerAuthorityEntity p : data) {
hashSet.add(p.getAuthorityCode());
}
List<SysMenuEntity> sysMenuEntities = staticSysMenuDao.selectPerms();
for (SysMenuEntity sysMenuEntity : sysMenuEntities) {
if (hashSet.contains(sysMenuEntity.getProjectCode())) {
hashSet1.add(sysMenuEntity.getPerms());
}
}
staticRedisUtils.set("auth:" + token, hashSet1);
}
/**
* 是否存在注解,如果存在就获取
*/
private UserAuth getAnnotationLog(JoinPoint joinPoint) {
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method != null) {
return method.getAnnotation(UserAuth.class);
}
return null;
}
public static <T> List<T> mapList(Collection sourceList, Class<T> destinationClass) {
DozerBeanMapper dozer = new DozerBeanMapper();
List<T> destinationList = new ArrayList<>();
for (Object sourceObject : sourceList) {
T destinationObject = dozer.map(sourceObject, destinationClass);
destinationList.add(destinationObject);
}
return destinationList;
}
}
3:实体类
package cn.wanda.common.base;
import lombok.Data;
/**
* @author : WangYuanYi
* @description :
* @create :2021-11-17 15:50:00
*/
@Data
public class UserAuthEntity {
private String token;
}
4:枚举类
package cn.wanda.common.typeenum;
/**
* @author : WangYuanYi
* @description :
* @create :2021-11-17 15:50:00
*/
public enum UserAuthEnum {
/**
* Token
*/
TOKEN,
}