欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-07-10 18:43:19
我们知道权限控制是不能交给前端去做的,因为一但后端的接口所暴露,是十分危险的一件事,所以前端发起的请求的安全性无从考证,最终的权限控制还是要交给后端去判断。Shiro和SpringSecurity是都具备权限控制的两个框架,但是如果自己的小项目在权限控制方面要求比较简单,那么这两个框架就显得有些“重”,而且SpringSecurity配置起...

       我们知道权限控制是不能交给前端去做的,因为一但后端的接口所暴露,是十分危险的一件事,所以前端发起的请求的安全性无从考证,最终的权限控制还是要交给后端去判断。
       ShiroSpringSecurity是都具备权限控制的两个框架,但是如果自己的小项目在权限控制方面要求比较简单,那么这两个框架就显得有些“重”,而且SpringSecurity配置起来还比较麻烦。
       本文所实现的权限控制是按等级划分的,即所有用户(游客、普通用户、管理员、超级管理员等)都有一个type字段来标识其身份:
Springboot自定义注解实现简单的接口权限控制,替代Shiro/SpringSecurity
       例如-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(); } 

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

本文地址:https://blog.csdn.net/weixin_42822484/article/details/107893586