RBAC权限验证

User实体类(用户)

@ApiModel("用户实体")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Long id;
    @ApiModelProperty(value = "昵称")
    private String name;
    @ApiModelProperty(value = "用户名")
    private String username;
    private String password;
    private Double balance;
    /**
     * 存储用户所有的菜单信息
     */
    @TableField(exist = false)
    Set<String> menuUrlList;


//    @TableField(exist = false)
//    Set<String> menuAuthStrList;


    public static void main(String[] args) {
        User user = new User();
        user.setName("xxxx");
        System.out.println(user);
    }
}

Role实体类 (角色)

@Data
public class Role{
    private Long id;
    private String name;
}

Menu实体类(菜单)

public class Menu{
    private Long id;
    private String name;
    private String url;
    private String authStr;
    private Long parentId;
}

RoleMapper

public interface RoleMapper extends BaseMapper<Role> {
}

MenuMapper

public interface MenuMapper extends BaseMapper<Menu> {
}

MenuService

public interface MenuService extends IService<Menu> {

    Set<String> listUrlByUserId(Long id);

}

MenuServiceImpl

注:这里本该是多对多连表查询到数据,这里用add模拟查询到的数据

@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {


    @Override
    public Set<String> listUrlByUserId(Long id) {
        // 1.根据用户ID查询到所有的角色ID  user-role
        // 2.根据所有角色ID查询到所有的菜单ID=>所有的菜单路径信息 role-menu
        // 总结:通过一条sql也是可以实现。
        Set<String> menuUrlList = new HashSet<>();
        // 模拟数据查询
        menuUrlList.add("/");
        menuUrlList.add("/index");
        menuUrlList.add("/testTr");
        return menuUrlList;
    }
}

UserController(用户登录)

LoginInterceptor拦截器

 

逻辑关系 

 

权限字符串,一个权限字符串对应多个接口

注解类


@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface HasAuth {

    /**
     * 权限字符串
     * @return
     */
    String  value() default "";
}

User实体类

@ApiModel("用户实体")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Long id;
    @ApiModelProperty(value = "昵称")
    private String name;
    @ApiModelProperty(value = "用户名")
    private String username;
    private String password;
    private Double balance;


    @TableField(exist = false)
    Set<String> menuAuthStrList;


    public static void main(String[] args) {
        User user = new User();
        user.setName("xxxx");
        System.out.println(user);
    }
}

UserController登陆成功后

if(userDb != null){
            // 获取用户所有的权限信息
            Set<String> menuAuthList = menuService.listAuthStrByUserId(userDb.getId());
            userDb.setMenuAuthStrList(menuAuthList);
            // 登陆成功了
            String token = TokenUtil.generateToken(userDb);
            map.put("code",1);
            map.put("data",userDb);
            map.put("token",token);
//            session.setAttribute("username",userDb.getUsername());
        }else{
            map.put("msg","用户名或密码错误!");
        }
MenuService
public interface MenuService extends IService<Menu> {


    Set<String> listAuthStrByUserId(Long id);
}
MenuServiceImpl
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    @Override
    public Set<String> listAuthStrByUserId(Long id) {
        // 2.根据所有角色ID查询到所有的菜单ID=>所有的菜单路径信息 role-menu
        // 总结:通过一条sql也是可以实现。
        Set<String> menuAuthStrList = new HashSet<>();
        // 模拟数据查询
        menuAuthStrList.add("hello:select");
        return menuAuthStrList;
    }
}

拦截器

       if (!TokenUtil.verify(token)) {
            // 未登录跳转到登录界面
           throw  new RuntimeException("no login!");
        } else {

            //通过反射拿到注解
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            HasAuth hasAuth = handlerMethod.getMethodAnnotation(HasAuth.class);
            
            if (hasAuth != null){
                /**
                 * 登陆验证通过=>验证权限信息
                 */
                //根据token拿到user
                User user = TokenUtil.getUser(token);
                //根据user拿到权限字符串
                Set<String> menuAuthStrList = user.getMenuAuthStrList();
                //如果接口的注解不在user的权限中说明权限不足
                if(!menuAuthStrList.contains(hasAuth.value())){
                    // 权限不足进制访问
                    throw  new RuntimeException("403 forbidden!");
                }
            }

            return true;
        }

这个相当于一个注解是一个权限字符串,一个注解可以表示多个接口,只需要在方法的上面加注解,使用这个接口的时候就会将这个的注解通过反射的方式拿到,然后用户权限验证,看看这个反射的权限字符串在不在用户的菜单权限字段中,如果在就说明有权限

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值