Springboot自定义注解实现简单的接口权限控制,替代Shiro/SpringSecurity

       我们知道权限控制是不能交给前端去做的,因为一但后端的接口所暴露,是十分危险的一件事,所以前端发起的请求的安全性无从考证,最终的权限控制还是要交给后端去判断。
       ShiroSpringSecurity是都具备权限控制的两个框架,但是如果自己的小项目在权限控制方面要求比较简单,那么这两个框架就显得有些“重”,而且SpringSecurity配置起来还比较麻烦。
       本文所实现的权限控制是按等级划分的,即所有用户(游客、普通用户、管理员、超级管理员等)都有一个type字段来标识其身份:
在这里插入图片描述
       例如-1指游客、0是普通用户、1是VIP、2是管理员、3是超级管理员等以此类推。这个字段即充当其“角色”,又充当其“权限(等级)”。其中低等级用户不能请求高等级的接口,高等级用户向下兼容,可以访问低等级的接口。
       详细代码如下,首先是:

1. 权限枚举类

       我们首先要把权限枚举类定义出来:

public enum AccessLevel {

    ALL(-1, "all"),
    LOGIN(0, "login"),
    VIP(1, "vip"),
    ADMIN(2, "admin"),
    SUPER(3, "super");

    int code;
    String msg;

    AccessLevel(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

2. 自定义权限控制注解

       其次是用在每个接口方法上的权限控制注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented     // 在生成javac时显示该注解的信息
@Inherited
public @interface Access {
    AccessLevel level() default AccessLevel.ALL; //默认为ALL
}

3. 自定义权限拦截器

       其次是自定义权限拦截器Interceptor:

@Component
public class AccessInterceptor extends HandlerInterceptorAdapter {

    private Logger logger = LoggerFactory.getLogger(AccessInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        Access access = method.getAnnotation(Access.class);
        if (access == null) {
            // 如果注解为null, 说明不需要拦截, 直接放过
            return true;
        }

        // 如果是所有都能访问权限直接放行
        if (access.level() == AccessLevel.ALL) {
            return true;
        }
        if (access.level().getCode() >= AccessLevel.LOGIN.getCode()) {
        	//这里为自己写的获取登录用户的信息的方法,大家可以根据自己的方法修改
            User user = UserUtils.getLoginUser();
            if (user == null || user.getId() == null) {
                response.setStatus(401);
                logger.info("access " + method.getName() + " Not logged in");
                return false;
            }
            if (user.getType() < access.level().getCode()) {
                response.setStatus(403);
                logger.info("access " + method.getName() + " No authority");
                return false;
            }
        }
        return true;
    }

4. 使用自定义权限拦截器

       我们需要使该拦截器生效:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AccessInterceptor());
    }
}

5. 使用

       我们需要在方法上使用该注解:

@GetMapping("/test")
@Access(level = AccessLevel.VIP)
public AjaxResponse test(){
	AjaxResponse.setData("测试成功!");
	return AjaxResponse.newSuccess();
}

       这样我们就可以自己来实现最简单权限控制,大家还可以灵活去更改权限和拦截器。

你可能感兴趣的:(springboot,springboot,权限控制)