当前位置 博文首页 > 蜗牛为梦想而生H:SpringBoot权限管理-按钮级别权限

    蜗牛为梦想而生H:SpringBoot权限管理-按钮级别权限

    作者:[db:作者] 时间:2021-09-07 19:23

    1.需要按钮具备权限标识

    1.1.存储数据库列表

    .

    1.2.登录信息Redis

    1.3.代码实例(以admin为例):

    AdminController.java

    @RestController
    @RequestMapping("admin")
    @RequiredArgsConstructor//使用lombok中此注解 不用写@Autowired
    public class AdminController extends BaseController {
    
    
        private final AdminService adminService;
        private final AdminExcelTransfer adminExcelTransfer;
        @Autowired
        private BCryptPasswordEncoder bCryptPasswordEncoder;
    
        @GetMapping
        public AxiosResult<PageResult<AdminVo>> list(AdminCriteria adminCriteria) {
            PageResult<AdminVo> pageResult = adminService.searchPage(adminCriteria);
            return AxiosResult.success(pageResult);
        }
    
        @GetMapping("{id}")
        public AxiosResult<Admin> findById(@PathVariable Long id) {
            //根据id回显
            Admin byId = adminService.getAdminAndRoleIdsById(id);
    
            return AxiosResult.success(byId);
        }
    
        @HasPerm(perm = "admin:add")
        @PostMapping
        public AxiosResult<Void> add(@RequestBody Admin admin) {
            //bCryptPasswordEncoder: String加密
            String adminPwd = admin.getAdminPwd();
            admin.setAdminPwd(bCryptPasswordEncoder.encode(adminPwd));
            admin.setIsAdmin(false);
            return toAxios(adminService.saveAdminAndRoles(admin));
        }
    
        @HasPerm(perm = "admin:edit")
        @PutMapping
        public AxiosResult<Void> update(@RequestBody Admin Admin) {
            //要修改本身 还要修改角色
            //return toAxios(adminService.update(Admin));
    
            return toAxios(adminService.updateAdminAndRoles(Admin));
        }
    
        @HasPerm(perm = "admin:delete")
        @DeleteMapping("{id}")
        public AxiosResult<Void> deleteById(@PathVariable Long id) {
            return toAxios(adminService.deleteById(id));
        }
    
        /*
         * 批量删除
         * */
        @HasPerm(perm = "admin:batch")
        @DeleteMapping("batch/{ids}")
        public AxiosResult<Void> batchDeleteByIds(@PathVariable List<Long> ids) {
            return toAxios(adminService.batchDeleteByIds(ids));
        }
    }

    1.4.自定义注解,使其在按钮执行之前执行这个注解,是否有权CRUD

    ?HasPerm.java

    /**
     * 写一个自定义注解 使其在按钮执行之前执行这个注解,是否有权CRUD
     */
    @Retention(RetentionPolicy.RUNTIME) //运行时异常
    @Target(ElementType.METHOD) //放在类上
    public @interface HasPerm {
    
        String perm() default  "";
    }
    

    1.5.?创建一个切面,进行前置通知管理

    package com.shangma.cn.common.permission;
    
    import com.cn.common.http.EnumStatus;
    import com.cn.common.utils.ServletUtils;
    import com.cn.common.utils.TokenService;
    import com.cn.domin.entity.Menu;
    import com.cn.exception.PermException;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.Signature;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.lang.reflect.Method;
    import java.util.List;
    
    /**
     * 创建一个切面
     */
    @Aspect //他是一个切面
    @Component //放到容器中
    public class MyAspect {
        //使用token,获取登录用户信息,获取权限
        @Autowired
        private TokenService tokenService;
    
        /**
         * 1.前置通知
         *
         * @param joinPoint 里面需要连接点JoinPoint
         */
        @Before("pointCut()")
        public void checkPerm(JoinPoint joinPoint) {
            //Signature 他是一个接口 找到他的被继承的接口(MethodSignature) ,转换一下
            //joinPoint.getSignature()作用: 获取封装了署名信息的对象,在该对象中可以获取到目标方法名,所属类的Class等信息
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    
            //拿到方法,拿到这个被注解定义的方法
            Method method = signature.getMethod();
            HasPerm annotation = method.getAnnotation(HasPerm.class);
    
            //拿到之后,就拿到方法的注解内容,如果注解不为空
            if (annotation != null) {
                String perm = annotation.perm();
    
                //判断用户有没有这个权限 拿到权限信息
                List<Menu> perms = tokenService.getLoginAdmin().getPerms();
    
                //stream().anyMatch() 有任何一个匹配都行
                //menu.getPermission(); 可能为空 不是按钮权限 没有权限标识 的判断
                boolean b = perms.stream().anyMatch(menu -> perm.equals(menu.getPermission()));
                if (!b) {
                    System.out.println("打印了: 进入权限判断了!");
                    //抛出异常 防止继续执行
                    throw new PermException(EnumStatus.NO_PREM);
    
                }
    
               /* //返回前端一个json信息
                String str = "{\"status\":000000,\"message\":\"无权限\"}";
                HttpServletResponse response = ServletUtils.getResponse();
                response.setContentType("application/json;charset=utf-8");
                response.getWriter().write(str);*/
            }
        }
    
        /**
         * 2.需要一个 切入点
         */
        @Pointcut("@annotation(com.shangma.cn.common.permission.HasPerm)")
        public void pointCut() {
    
        }
    
    }
    

    1.6.权限 运行时异常

    package com.cn.exception;
    
    import com.cn.common.http.EnumStatus;
    
    /**
     * 处理 权限验证 运行时异常
     */
    
    public class PermException extends RuntimeException {
    
        private EnumStatus enumStatus;
    
        public PermException(EnumStatus enumStatus) {
            this.enumStatus = enumStatus;
        }
    
        public EnumStatus getEnumStatus() {
            return enumStatus;
        }
    
        public void setEnumStatus(EnumStatus enumStatus) {
            this.enumStatus = enumStatus;
        }
    }
    
    

    1.7.处理异常

    package com.cn.exception;
    
    import com.cn.common.http.AxiosResult;
    import com.cn.common.http.EnumStatus;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RestControllerAdvice;
    
    import java.util.Map;
    
    /**
     * 专门做处理异常的
     */
    @RestControllerAdvice
    public class MyExceptionHandler {
    
        /**
         * 处理权限异常
         */
        @ExceptionHandler(PermException.class)
        public AxiosResult<Void> handler(PermException e){
            EnumStatus enumStatus = e.getEnumStatus();
    
            return AxiosResult.error(enumStatus);
    
        }
    }
    

    2.附录:

    2.1.枚举异常类:EnumStatus.java

    package com.cn.common.http;
    
    public enum EnumStatus {
        OK(20000,"操作成功"),
        ERROR(40000,"操作失败"),
        NO_LOGIN(40005,"未登录"),
        ACCOUNT_ERROR(40006,"用户名错误"),
        CODE_ERROR(40007,"验证码错误"),
        PWD_ERROR(40007,"密码错误"),
        CODE_LOSE(40008,"验证码失效"),
        NO_ACTIVE(40009,"用户邮箱未激活"),
        NO_PREM(40010,"无权限");
    
        private int status;
        private String message;
    
        EnumStatus(int status, String message) {
            this.status = status;
            this.message = message;
        }
    
        public int getStatus() {
            return status;
        }
    
        public void setStatus(int status) {
            this.status = status;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    }
    

    2.2.统一返回值类:?AxiosResult.java

    package com.cn.common.http;
    
    import com.fasterxml.jackson.annotation.JsonInclude;
    
    /*表示这个类 在转json格式字符串是,如果属性有null,则json字符串中不会有这个属性 */
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public class AxiosResult<T> {
        private int status;
        private String message;
        private T data;
    
    
        private static <T> AxiosResult<T> getAxiosResult(EnumStatus enumStatus, T data){
            return new AxiosResult<T>(enumStatus,data);
        }
        public static <T> AxiosResult<T> error(EnumStatus enumStatus) {
            return getAxiosResult(enumStatus, null);
        }
        public AxiosResult(EnumStatus enumStatus, T data){
            this.message=enumStatus.getMessage();
            this.status=enumStatus.getStatus();
            this.data=data;
        }
    
        public int getStatus() {
            return status;
        }
    
        public void setStatus(int status) {
            this.status = status;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public T getData() {
            return data;
        }
    
        public void setData(T data) {
            this.data = data;
        }
    
        /**
         * 返回成功的方法
         */
        public static <T> AxiosResult<T> success(){
           return getAxiosResult(EnumStatus.OK,null);
        }
    
        public static <T> AxiosResult<T> success(T data){
            return getAxiosResult(EnumStatus.OK,data);
        }
    
        /**
         * 返回失败的方法
         */
        public static <T> AxiosResult<T> error(T data){
            return getAxiosResult(EnumStatus.ERROR,data);
        }
    
        public static <T> AxiosResult<T> error(){
            return getAxiosResult(EnumStatus.ERROR,null);
        }
    }
    

    3.效果

    前端登录该用户, 点击删除, 无权限

    Gitee源码地址: 暂未发布

    ?

    cs
    下一篇:没有了