AOP实现RBAC权限验证

首先引入AOP的依赖

         
            org.springframework.boot
            spring-boot-starter-aop
        
TokenUtil工具类 

作用:1.通过用户生成token

           2.通过token 验证用户是否登录

           3.通过token获取用户实体类

 

public class TokenUtil {

    private static Map tokenMap = new HashMap<>();

    public static String generateToken(User user){
        String token = UUID.randomUUID().toString();
        tokenMap.put(token,user);
        return token;
    }

    public static boolean verify(String token){
        return tokenMap.containsKey(token);
    }

    public static User getUser(String token){
        return tokenMap.get(token);
    }
}

AuthorityAop

作用:在调用方法的时候,拿到HEAD中的token,通过tokenUtil工具类获取用户,并通过连表查询查询到用户的权限字段menu,验证注解中的value是否在用户的权限字段中

@Component
@Aspect
public class AuthorityAop {
    @Autowired
    private HttpServletRequest httpServletRequest;


    //定义切入点   切入点就HasAuth注解标注的地方
    @Pointcut("@annotation(com.example.aoptest.common.annonation.HasAuth)")
    public void AuthorityAopPointCut() {

    }
    //环绕
    @Around("AuthorityAopPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        //在调用方法的时候,拿到HEAD中的token,通过tokenUtil工具类获取用户,并通过连表查询查询到用户的权限字段menu,验证注解中的value是否在用户的权限字段中

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        HasAuth viewRecords = method.getAnnotation(HasAuth.class);
        String idValue = viewRecords.value();
        String token = httpServletRequest.getHeader(GlobalConstant.HEAD_TOKEN);
        User user = TokenUtil.getUser(token);
        Set menuList = user.getMenu();
        if (!menuList.contains(idValue)) {
            throw new RuntimeException("权限不足");
        }
        //执行方法
        return joinPoint.proceed();
    }
}
GlobalConstant        全局变量类
public class GlobalConstant {
    public final static String HEAD_TOKEN="token";
}

aop中直接根据这个全局变量拿就ok了

HasAuth        注解类

@Target(ElementType.METHOD)
@Retention(RUNTIME)
public @interface HasAuth {
    String value() default "";
}

使用注解的时候这样用

@HasAuth(value = "menu1")

在方法前用这个注解,可以通过反射获取注解中的值,在aop中可以把注解中的值当作权限字符串,要求登录的用户有这个字符串权限才能访问

 

Controller

在登录的时候,拿到用户的id,通过用户id查到对应用户的权限字符串,把用户的权限字符串set进用户实体类中,并调用TokenUtil的生成token的方法,生成一串token

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;


    @PostMapping("/login")
    public WebResultJson login(@RequestBody User user){
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username",user.getUsername());
        queryWrapper.eq("password",user.getPassword());
        User user1 =  userService.getOne(queryWrapper);
        if(user1!=null){
            Long userId = user1.getId();
            Set menuList= userService.getMenu(userId);
            user1.setMenu(menuList);
            String token = TokenUtil.generateToken(user1);
            return WebResultJson.ok(token);
        }
        return WebResultJson.fail();
    }

    @PostMapping("/test")
    @HasAuth(value = "menu1")
    public WebResultJson test(){
       return WebResultJson.ok("我真厉害!");
    }

}

 AOP实现RBAC权限验证_第1张图片AOP实现RBAC权限验证_第2张图片

 

 如果不在HEAD中加token

AOP实现RBAC权限验证_第3张图片

就会报错 

User 用户实体类

@Data
@TableName("user")
public class User {
    @TableId
    private Long id;
    private String username;
    private String password;

    @TableField(exist = false)
    private Set menu;
}

 xml




    

mapper

public interface UserMapper extends BaseMapper {
    public Set getMenu(@Param("userId")Long userId);
}

数据库

AOP实现RBAC权限验证_第4张图片

AOP实现RBAC权限验证_第5张图片 

AOP实现RBAC权限验证_第6张图片 

AOP实现RBAC权限验证_第7张图片 

通过(用户id)   查  (角色id)   根据(角色id)查  (权限id)    

就可以查到对应用户的权限,返回的是Set类型

你可能感兴趣的:(衔接,java,spring,boot)