美文网首页Spring-Bootjava学习springbootJava 杂谈
springboot借助aop和注解实现权限校验

springboot借助aop和注解实现权限校验

作者: 编程小石头666 | 来源:发表于2019-02-18 20:01 被阅读10次

    我们用springboot做后台开发,难免会用到权限校验,比如查看当前用户是否合法,是否是管理员。而spring的面向切面的特效可以帮助我们很好的实现动态的权限校验。这里我们就用到的spring的aop。接下来就带领大家用aop和注解来快速的实现权限校验

    一,在pom.xml里引入aop的类库。

    <!--aop切面的使用-->
    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    

    二,自定义注解

    package com.demo.permission;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * Created by qcl on 2019/2/18
     * 微信:2501902696
     * desc:自定义权限管理注解
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Permission {
        String authorities() default "我是默认值";
    }
    

    三,借助@Aspect实现切面

    package com.demo.permission;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.util.StringUtils;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.lang.reflect.Method;
    
    import javax.security.auth.login.LoginException;
    
    @Aspect
    @Component
    public class ControllerAspect {
    
        private final static Logger logger = LoggerFactory.getLogger(ControllerAspect.class);
    
        @Autowired
        private UserService userService;
    
        /**
         * 定义切点
         */
        @Pointcut("execution(public * com.demo.permission.controller.*.*(..))")
        public void privilege() {
        }
    
        /**
         * 权限环绕通知
         *
         * @param joinPoint
         * @throws Throwable
         */
        @ResponseBody
        @Around("privilege()")
        public Object isAccessMethod(ProceedingJoinPoint joinPoint) throws Throwable {
            //获取访问目标方法
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
            Method targetMethod = methodSignature.getMethod();
            //得到方法的访问权限
            final String methodAccess = AnnotationParse.privilegeParse(targetMethod);
    
            //如果该方法上没有权限注解,直接调用目标方法
            if (StringUtils.isEmpty(methodAccess)) {
                return joinPoint.proceed();
            } else {
                //获取当前用户
                Object[] args = joinPoint.getArgs();
                if (args == null) {
                    throw new LoginException("参数错误");
                }
                String currentUser = args[0].toString();
                logger.info("访问用户,{}", currentUser);
                if (!userService.isAdmin(currentUser)) {
                    throw new LoginException("您不是管理员");
                } else {
                    logger.info("您是管理员");
                    //是管理员时,才返回所需要的信息
                    return joinPoint.proceed();
                }
    
            }
        }
    }
    

    四,定义一个简单的管理员名单

    package com.demo.permission;
    
    import org.springframework.stereotype.Service;
    
    import java.util.Arrays;
    
    /**
     * Created by qcl on 2019/2/18
     * 微信:2501902696
     * desc:
     */
    @Service
    public class UserService {
        private String[] admins = {"qiushi", "weixin", "xiaoshitou"};
    
        //是否是管理员
        boolean isAdmin(String name) {
            return Arrays.asList(admins).contains(name);
        }
    }
    

    这里简单起见,就用一个本地的数组来维护管理员,正常应该是把管理员相关信息存到数据库里。

    五,获取用户名,@Permission注解进行权限校验

    package com.demo.permission.controller;
    
    import com.demo.permission.Permission;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    import lombok.extern.slf4j.Slf4j;
    
    /**
     * Created by qcl on 2019/2/18
     * 微信:2501902696
     * desc:
     */
    @RestController
    @Slf4j
    public class UserController {
    
        //带注解,需要校验权限
        @GetMapping(value = "/user")
        @Permission
        public String user(@RequestParam String name) {
            return "你好:"+name+",您有管理权限";
        }
    
        //不带注解,不需要安全校验
        @GetMapping(value = "/user2")
        public String user2(@RequestParam String name) {
            return "不用检查权限,直接返回的数据";
        }
    
    }
    

    然后通过url请求来验证结果
    1,http://localhost:8080/user?name=qcl2

    image.png
    由于qcl2不在管理员数组里面,所以抛出异常
    2,http://localhost:8080/user?name=qiushi
    image.png
    qiushi是管理员,所以用户邱石可以访问到数据。
    3,http://localhost:8080/user2?name=qiushi
    image.png
    由于接口/user2没有添加 @Permission注解,所以不用做安全校验,直接返回数据。
    image.png

    到这里我们就轻松实现通过 @Permission一个注解,就可以实现数据的安全校验。

    相关文章

      网友评论

        本文标题:springboot借助aop和注解实现权限校验

        本文链接:https://www.haomeiwen.com/subject/uquzeqtx.html