当前位置:   article > 正文

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

shiro 如何替代

       我们知道权限控制是不能交给前端去做的,因为一但后端的接口所暴露,是十分危险的一件事,所以前端发起的请求的安全性无从考证,最终的权限控制还是要交给后端去判断。
       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;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

2. 自定义权限控制注解

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

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

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;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

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

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

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AccessInterceptor());
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

5. 使用

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

@GetMapping("/test")
@Access(level = AccessLevel.VIP)
public AjaxResponse test(){
	AjaxResponse.setData("测试成功!");
	return AjaxResponse.newSuccess();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/933789
推荐阅读
相关标签
  

闽ICP备14008679号