springboot+自定义注解+AOP切面实现单个接口权限控制

除了标题中的功能,其实这种方式可以用到很多功能方面,在解耦方面起着巨大的效果

项目中需要对每一个权限做权限控制

切面主要能起到解耦效果,但是扫描是扫一片的,不能灵活设置,这时候想到了注解,哪边需要扫描就在哪个接口加注解。优点是:代码量少,灵活。

屁话不多说,直接上码

1,自定义注解

package com.movitech.contract.config;

import java.lang.annotation.*;

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Oauth {

}

2,切面(设计到了数据库操作,不贴代码了,很简单~)

package com.movitech.contract.config;

import com.movitech.commons.utils.StringUtil;
import com.movitech.contract.dao.OauthDao;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;


@Aspect //  声明切面
@Component //声明组件
@ComponentScan //组件自动扫描
@EnableAspectJAutoProxy //spring自动切换JDK动态代理和CGLIB
public class OauthAspect {
    @Autowired
    private OauthDao oauthDao;
    @Before("execution(public * com.movitech.contract.controller.*.*(..)) && @annotation(com.movitech.contract.config.Oauth)")
    public void doOauth(JoinPoint point) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        //获取调用者带来的token
        Object token = request.getHeaders("token").nextElement();
        //截取请求的uri
        String requestUri = request.getRequestURI();
        int num = requestUri.length() - requestUri.replace("/","").length();
        if(num >= 4){
            //截取/a/b/c三层后面的字符
            requestUri = getStr(requestUri,3);
        }
        System.out.println("token:"+token+"======="+"requestUri:"+requestUri);
        //根据uri来获取接口开发状态
        Integer isValid = oauthDao.getIsValid(requestUri);
        if(StringUtil.isEmpty(isValid)){
            System.out.println("接口状态:关闭!");
            throw new Exception("接口状态:关闭,不允许访问!");
        }else {
            if(isValid == 1){
                System.out.println("接口状态:可用!");
            }else{
                System.out.println("接口状态:关闭!");
                throw new Exception("接口状态:关闭,不允许访问!");
            }
        }

        //根据uri来获取鉴权约定的token
        String id = oauthDao.getId(requestUri);
        //判断是否一致,是:放行;否则抛出异常
        if(token.equals(id)){
            System.out.println("权限通过,放行");
        }else {
            throw new Exception("权限不满足,不允许访问次接口!请先去鉴权!!");
        }
    }
    private static String getStr(String str, int n) {
        int i = 0;
        int s = 0;
        while (i++ < n) {
            s = str.indexOf("/", s + 1);
            if (s == -1) {
                return str;
            }
        }
        return str.substring(0, s);
    }
}

3,接口controller

package com.movitech.contract.controller;

import com.movitech.contract.config.Oauth;
import com.movitech.contract.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @Autowired
    private HelloService helloService;

    @GetMapping("/a/b/c/d/e/f")
    @Oauth
    public String hello(String name) {
        String result = "nihao3";
        return result;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_34707991/article/details/81567894