在springboot中使用拦截器进行鉴权操作

文章详细描述了数据库设计中的表结构创建、数据插入以及使用UserMapper接口获取用户权限的SQL查询。同时展示了如何在SpringMVC中使用拦截器进行权限检查,确保只有特定用户可以访问/sys路径下的资源。
摘要由CSDN通过智能技术生成

数据库设计

create databse rbacdb;
use rbacdb
-- ----------------------------
-- Table structure for sys_role_menu
-- ----------------------------
DROP TABLE IF EXISTS `sys_role_menu`;
CREATE TABLE `sys_role_menu` (
  `role_id` int(11) NOT NULL,
  `menu_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_role_menu
-- ----------------------------
INSERT INTO `sys_role_menu` VALUES ('4', '6');
INSERT INTO `sys_role_menu` VALUES ('4', '7');
INSERT INTO `sys_role_menu` VALUES ('5', '7');
INSERT INTO `sys_role_menu` VALUES ('5', '8');

-- ----------------------------
-- Table structure for sys_user_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role` (
  `user_id` int(11) NOT NULL,
  `role_id` int(11) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_user_role
-- ----------------------------
INSERT INTO `sys_user_role` VALUES ('18', '4');
INSERT INTO `sys_user_role` VALUES ('19', '5');

-- ----------------------------
-- Table structure for t_menu
-- ----------------------------
DROP TABLE IF EXISTS `t_menu`;
CREATE TABLE `t_menu` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `menu_name` varchar(255) NOT NULL,
  `menu_path` varchar(255) NOT NULL,
  `desc` varchar(255) NOT NULL,
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `is_delete` char(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of t_menu
-- ----------------------------
INSERT INTO `t_menu` VALUES ('6', '用户管理', '/sys/user', '1', '2023-10-21 15:08:45', '0');
INSERT INTO `t_menu` VALUES ('7', '评论管理', '/sys/pinglun', '111', '2023-10-21 15:08:41', '0');
INSERT INTO `t_menu` VALUES ('8', '测试', '/sys/test', '111', '2023-10-21 16:43:12', '0');

-- ----------------------------
-- Table structure for t_role
-- ----------------------------
DROP TABLE IF EXISTS `t_role`;
CREATE TABLE `t_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `role_name` varchar(100) NOT NULL,
  `desc` varchar(200) DEFAULT NULL,
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `is_delete` char(1) DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of t_role
-- ----------------------------
INSERT INTO `t_role` VALUES ('4', '超级管理员', '权限最高', '2023-10-21 15:06:10', '0');
INSERT INTO `t_role` VALUES ('5', '普通用户', '权限很低', '2023-10-21 15:06:25', '0');

-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `account` varchar(18) NOT NULL,
  `password` varchar(500) NOT NULL,
  `sex` char(1) NOT NULL,
  `nickname` varchar(50) NOT NULL,
  `img_url` varchar(255) DEFAULT NULL,
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `is_delete` char(1) DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `account` (`account`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES ('18', 'admin', '111', '1', '管理员', 'xxx', '2023-10-21 15:05:27', '0');
INSERT INTO `t_user` VALUES ('19', 'test', '111', '1', '普通用户', 'xxx', '2023-10-21 15:05:49', '0');

编写接口


@RestController
public class LoginController {
    @Autowired
    private UserMapper userMapper;
    @GetMapping("/login")
    public String login(@RequestBody User user){
        LambdaQueryWrapper<User>warpper=new LambdaQueryWrapper<>();
        warpper.eq(User::getAccount,user.getAccount());
        warpper.eq(User::getPassword,user.getPassword());
        User user1 = userMapper.selectOne(warpper);
        if (!Objects.isNull(user1)){
            String token = JwtUtils.getToken(user1.getId().toString());
            return token;
        }
        return "账号密码错误";
    }
}
@RestController
@RequestMapping("/sys")
public class PingLunController {
    @GetMapping("/pinglun/getpinglun")
    public String getPingLun(){
        return "获取评论成功";
    }
}
@RestController
@RequestMapping("/sys")
public class UserController {
    @GetMapping("/user/getUser")
    public String getUser(){
        return "获取用户成功";
    }
    @GetMapping("/test/abcd/test")
    public String test(){
        return "获取成功";
    }
}

编写一个查找用户权限的接口

UserMapper中
public interface UserMapper extends BaseMapper<User> {
    List<String> getMenu(String userId);
}

userMapper.xml中
 <select id="getMenu" resultType="java.lang.String">
        select
            DISTINCT
            m.menu_path
        from t_user u,t_role r,t_menu m,sys_role_menu rm,sys_user_role ur
        where
            u.id=ur.user_id and r.id=ur.role_id and m.id=rm.menu_id and r.id=rm.role_id and u.id=19
    </select>

拦截器规则

@Component
public class Interceptor implements HandlerInterceptor {
    @Autowired
    private UserMapper userMapper;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器执行");
        System.out.println(request.getRequestURI());// 打印请求路径

        String token=request.getHeader("token"); //获取请求头中的token
        if (!StringUtils.hasText(token)){
            throw new TokenException("token为空"); //这里抛出的异常会进入全局异常处理类
        }
        String userId=null;
        try{
            Claims claims = JwtUtils.parseToken(token); //对token进行解析
             userId = claims.getSubject();
            System.out.println(userId);
        }catch (RuntimeException e){
            throw new TokenException("token异常");
        }


        //鉴权操作 如果路径出现/sys 则需要鉴权
        if (request.getRequestURI().indexOf("/sys")!=-1){
            String requestPath = request.getRequestURI(); //获取请求路径
            List<String> menuPath = userMapper.getMenu(userId); //获取该用户能访问的路径列表
            System.out.println(menuPath);
            for (String path : menuPath) {
                if(requestPath.indexOf(path)!=-1){  //如果访问路径包含放行路径则放行 如放行/sys/user 下所有路径 用户访问 /sys/user/getUser
                    return true;
                }
            }

            throw new RuntimeException("权限不足");
        }
        return true; //拦截器 返回false就是拦截,返回true就是放行
    }
}

拦截器配置类

@Configuration
public class webconfig implements WebMvcConfigurer {
    @Bean Interceptor myInterceptor(){ //对拦截器进行Bean处理,不然在拦截器里面拿不到其他Bean对象
        return new Interceptor();
    }
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor())
                .addPathPatterns("/sys/**");
    }
}

补充:我们在拦截器中抛出的异常会被全局异常处理类捕获并处理

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值