使用 SpringBoot + AOP 实现简单的用户权限控制

前置安排:这里的权限控制使用的是五张 MySQL 表:分别为:

用户表、角色表、权限表、用户角色表(存储用户id和角色id的绑定关系)、角色权限表(存储角色id和权限id的绑定关系)

1、自定义注解,读取自定义的权限码

@Target(ElementType.METHOD) //表示该注解只能用于方法上
@Retention(RetentionPolicy.RUNTIME) //表示注解会在运行时保留
public @interface CheckPermission {
    String[] value(); // 定义需要的权限
}
@Aspect
@Component
public class PermissionAspect {

    private final PermissionService permissionService;
    //private final HttpServletRequest request;

    public PermissionAspect(PermissionService permissionService) {
        this.permissionService = permissionService;
        //this.request = request;
    }

    @Before("@annotation(checkPermission)")
    public void checkUserPermission(JoinPoint joinPoint, CheckPermission checkPermission) throws Exception {
        // 从请求头中获取用户ID
        //String userIdHeader = request.getHeader("User-Id");
//        if (userIdHeader == null) {
//            throw new Exception("请求头中未找到 User-Id");
//        }

        Long userId = Long.parseLong("1");

        // 获取注解中所需的权限
        String[] requiredPermissions = checkPermission.value();

        // 校验用户是否具备指定权限
        for (String permission : requiredPermissions) {
            System.out.println("permission = " + permission);
            if (!permissionService.hasPermission(userId, permission)) {
                throw new Exception("用户无权访问: " + permission);
            }
        }
    }
}

注意:在 PermissionAspect 类中,去判断该用户是否拥有此权限。一般是根据用户的 id 传参,用户的id一般是在请求头中获取的,我这里为了方便,把用户的id写死为了 “1”。

@Service
public class PermissionService {

    @Autowired
    private PermissionMapper permissionMapper;
    
    public boolean hasPermission(Long userId, String permissionName) {
        Set<String> userPermissions = permissionMapper.selectPermissionByUserId(userId);
        for (String permission : userPermissions) {
            if (permission.equals(permissionName)) {
                return true;
            }
        }
        return false;
    }
}

2、根据用户的id关联查询权限码

@Mapper
public interface PermissionMapper {
    Set<String> selectPermissionByUserId(@Param("userId") Long userId);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.soft.mapper.PermissionMapper">

    <select id="selectPermissionByUserId" resultType="java.lang.String" parameterType="map">
        SELECT p.permission_name
        from users u
                 left join user_role ur on u.id = ur.user_id
                 left join roles r on ur.role_id = r.id
                 left join role_permission rp on r.id = rp.role_id
                 left join permissions p on rp.permission_id = p.id
        where u.id = #{userId}
    </select>
</mapper>

3、在controller层使用权限校验

@RestController
public class PermissopnController {

    //@CheckPermission({"100001", "100002"})
    @CheckPermission("100001")
    @GetMapping("/hello")
    public String test1(){
        return "hello world permission";
    }
}

注意:该权限码必须是该登录用户拥有的权限码,只有拥有权限码的用户才能访问该接口,如果是多个权限码,可以使用 {"权限码","权限码"} ,在这里多个权限码是并集。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值