【sentinel】授权规则详解及源码分析

news2025/1/24 14:30:01

之前我们在配置流控规则时,可以根据origin参数来对调用方进行限流。

很多时候,我们需要根据调用方来限制资源是否通过,这时候可以使用Sentinel的黑白名单控制的功能,这就是授权规则

黑白名单也是根据资源的请求来源(origin)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。

调用方信息通过ContextUtil.enter(resourceName, origin)方法中的origin参数传入。

可以实现接口RequestOriginParser来获取请求中的某个参数来标明调用方身份,例如可以从请求的Header中获取source字段来标明调用方身份,然后可以将source字段配置在授权规则中,可以根据source的值进行限制。

授权规则的配置

黑白名单规则(AuthorityRule)非常简单,主要有以下配置项:

  • resource:资源名,即授权规则的作用对象
  • limitApp:对应的黑名单/白名单,不同origin用逗号进行分隔,如appA,appB
  • strategy:限制模式,AUTHORITY_WHITE为白名单模式,AUTHORITY_BLACK为黑名单模式,默认为白名单模式

白名单:位于白名单内的资源可通过,不在白名单范围内的不可通过。

黑名单:位于黑名单内的资源不可通过,不在黑名单范围内的资源可通过。

授权规则的使用

比如我们希望控制对资源authorityTest的访问设置白名单,只有来源为appA和appB的请求才可通过,则可以配置如下白名单规则:

package com.morris.user.demo;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.context.ContextUtil;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
import lombok.extern.slf4j.Slf4j;

import java.util.Collections;
import java.util.Objects;

/**
 * 授权规则的使用
 */
@Slf4j
public class AuthorityDemo {
    public static void main(String[] args) {
        String origin = "appC";
        String resourceName = "authorityTest";
        // 手动创建Context,设置Origin
        ContextUtil.enter(resourceName, origin);
        
        // 配置授权规则,白名单模式
        AuthorityRule ruleB = new AuthorityRule()
                .setResource(resourceName)
                .setLimitApp("appA,appB")
                .as(AuthorityRule.class)
                .setStrategy(RuleConstant.AUTHORITY_WHITE);

        AuthorityRuleManager.loadRules(Collections.singletonList(ruleB));

        Entry entry = null;
        try {
            // Sentinel源码入口
            entry = SphU.entry(resourceName);
            log.info("业务逻辑... ");
        } catch (BlockException e) {
            log.error("block exception ", e);
        } finally {
            if (Objects.nonNull(entry)) {
                entry.exit();
            }
            System.exit(0);
        }

    }
}

授权规则的源码分析

授权规则的校验逻辑主要是通过AuthoritySlot实现的。

AuthoritySlot#entry会在调用目标方法之前进行校验是否在黑白名单内。

com.alibaba.csp.sentinel.slots.block.authority.AuthoritySlot#entry

public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count, boolean prioritized, Object... args)
    throws Throwable {
    checkBlackWhiteAuthority(resourceWrapper, context);
    fireEntry(context, resourceWrapper, node, count, prioritized, args);
}

    void checkBlackWhiteAuthority(ResourceWrapper resource, Context context) throws AuthorityException {
    // 获取通过AuthorityRuleManager.loadRules()加载的授权规则
    Map<String, Set<AuthorityRule>> authorityRules = AuthorityRuleManager.getAuthorityRules();

    if (authorityRules == null) {
        return;
    }

    // 根据资源名查找授权规则
    Set<AuthorityRule> rules = authorityRules.get(resource.getName());
    if (rules == null) {
        return;
    }

    for (AuthorityRule rule : rules) {
        // 遍历所有的授权规则,逐条校验
        if (!AuthorityRuleChecker.passCheck(rule, context)) {
            // 如果有一条规则不通过,则抛出AuthorityException,AuthorityException是BlockException的子类
            throw new AuthorityException(context.getOrigin(), rule);
        }
    }
}

拿到请求中的origin来源与规则中配置的app一一比较,判断是否在黑白名单内。

com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleChecker#passCheck

static boolean passCheck(AuthorityRule rule, Context context) {
    String requester = context.getOrigin();

    // Empty origin or empty limitApp will pass.
    if (StringUtil.isEmpty(requester) || StringUtil.isEmpty(rule.getLimitApp())) {
        return true;
    }

    // Do exact match with origin name.
    // 先粗略匹配,再精确匹配
    int pos = rule.getLimitApp().indexOf(requester);
    boolean contain = pos > -1;

    if (contain) {
        boolean exactlyMatch = false;
        // 按逗号进行分割
        String[] appArray = rule.getLimitApp().split(",");
        for (String app : appArray) {
            // 没有处理空格
            // 精确匹配
            if (requester.equals(app)) {
                exactlyMatch = true;
                break;
            }
        }

        contain = exactlyMatch;
    }

    int strategy = rule.getStrategy();
    if (strategy == RuleConstant.AUTHORITY_BLACK && contain) {
        // 在黑名单内
        return false;
    }

    if (strategy == RuleConstant.AUTHORITY_WHITE && !contain) {
        // 不在白名单内
        return false;
    }

    return true;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/521582.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vite跨域问题,你可能需要看这篇文章

最近在学习项目的时候&#xff0c;使用了vite工具进行构建&#xff0c;然后出现了跨域的问题&#xff0c;中间的曲折不过多叙述&#xff0c;直接进入正题。 前端成功启动后的界面&#xff1a; 然后在后端进行的Controller上使用了如下的配置 然后浏览器就会出现跨域的问题 为什…

Maven 依赖管理 学习

目录 Maven 依赖管理 可传递性依赖发现 依赖范围 依赖管理 Maven 自动化部署 问题描述 解决方案 修改项目的 pom.xml Maven Release 插件 Maven Web 应用 创建 Web 应用 构建 Web 应用 部署 Web 应用 Maven 依赖管理 Maven 一个核心的特性就是依赖管理。当我们处…

【场景生成与研究】考虑时序相关性MC的场景生成与削减研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Docker基础篇(下)

1、容器命令 新建启动容器 docker run [OPTIONS] IMAGE [COMMAND] [ARG...]常用的参数&#xff1a; ● --name&#xff1a;为容器指定一个名称 ● -d&#xff1a;后台运行容器并返回容器ID&#xff0c;也即启动守护式容器 ● -i&#xff1a;以交互模式&#xff08;interacti…

基于FPGA:运动目标检测(LCD显示+串口输出,纯Verilog工程)

目录 前言一、先看效果二、硬件选择三、系统框架四、程序模块1、系统顶层模块2、图像处理顶层模块3、LCD驱动顶层模块4、SDRAM控制器顶层模块5、上位机发送模块 五、工程及套件获取1、工程获取2、套件 前言 最早做了基于FPGA&#xff1a;运动目标检测&#xff08;VGA显示&#…

Java基础-面向对象总结(1)

本文主要梳理关于 Java面向对象的基础知识,希望对你有帮助 Java对象 目录 Java对象 Java创建对象有几种方式 创建一个对象用什么运算符? 对象实体与对象引用有何不同? 创建一个对象的步骤 Java对象都包含什么 ? new Object()对象占多少个字节? 对象的比较 对象的相…

kafka原理之生产者

batch.size:只有数据累计到batch.size后&#xff0c;sender才会发送数据。默认16k linger.ms:如果迟迟没有达到batch.size&#xff0c;sender等待linger.ms设置时间之后&#xff0c;发送数据。单位:ms,默认0(没有延迟) acks设置: 0:不需要等待数据落盘应答&#xff1b;1:leader…

Java ---多线程(下)

&#xff08;一&#xff09;目录 线程的优先级 守护线程 线程同步 线程并发协作 主要内容 &#xff08;二&#xff09;线程的优先级 1 什么是线程的优先级 每一个线程都是有优先级的&#xff0c;我们可以为每个线程定义线程的优先级&#xff0c;但是这并不能保 证高优…

Anaconda下载与安装详解

文章目录 1 Anaconda1.1 简介1.2 下载安装1.3 配置环境变量1.4 下载配置1.4.1 conda配置1.4.1.1 修改conda下载源1.4.1.2 删除下载源1.4.1.3 包下载目录1.4.1.4 下载报错 1.4.2 pip配置1.4.2.1 配置源1.4.2.2 下载目录1.4.2.3 修改下载目录 1.5 修改虚拟环境地址1.5.1 通过配置…

【软件开发】Memcached(理论篇)

Memcached&#xff08;理论篇&#xff09; 1.Memcached 简介 Memcached 是一个开源的&#xff0c;支持高性能&#xff0c;高并发的分布式内存缓存系统&#xff0c;由 C 语言编写&#xff0c;总共 2000 多行代码。从软件名称上看&#xff0c;前 3 个字符 Mem 就是内存的意思&am…

quartz原理

1.如何实现任务 2.3个组件 3.工作原理 在Quartz中&#xff0c;有两类线程&#xff0c;Scheduler调度线程和任务执行线程&#xff0c;其中任务执行线程通常使用一个线程池维护一组线程。 Scheduler调度线程主要有两个&#xff1a;执行常规调度的线程&#xff0c;和执行misfir…

【C++】关联式容器——mapset的使用

文章目录 1.关联式容器和键值对1. 关联式容器2. 键值对 2. 树形结构的关联式容器——set1. 模版参数列表2. 默认成员函数3. 迭代器4.容量相关操作5.modify6.其他操作接口 3. 树形结构的关联式容器——map1. 默认成员函数2. 迭代器3. 容量与数据访问4.数据修改5. 其他操作接口 1…

vue-5:router

router路由配置&#xff0c;使用 在vue-cli构建的vue单页面应用中&#xff0c;需要借助vue-router库实现路由功能 配置路由 (构建项目时要下载) router文件夹下创建&#xff1a;index.js&#xff0c;routerConfig.js配置路由 路由懒加载&#xff1a; 按需加载&#xff1a;…

轻松掌握线程基础知识和四种创建方式及区别

1、线程与进程 2、并行与并发 3、创建线程 1、方式一&#xff1a;继承Thread类 2、方式二&#xff1a;实现Runnable接口 3、方式三&#xff1a;实现Callable接口 4、方式四&#xff1a;线程池创建线程&#xff08;项目中使用的方式&#xff09; 5、Runnable和Callable区别 6、…

在 Windows 10/11、7/8 上清空后从回收站恢复已删除文件的 6 种方法

Windows&#xff08;包括 Windows 11、10、8、7 和 Vista&#xff09;上的回收站用于回收您打算删除的不需要的文件。如果您删除了一些重要的文件或文件夹并且不小心清空了回收站&#xff0c;您仍然有机会恢复从回收站中删除的文件。这是一个教程&#xff0c;将阐明“如何在清空…

HTML第一天

HTML第一天 我们接下来是进行的网页开发网页的相关概念: 什么是网页?什么是HTML?网页的形成? 什么是网页&#xff1a; 1.网站是指在因特网上根据一定的规则&#xff0c;使用 HTML 等制作的用于展示特定内容相关的网页集合。 2.网页是网站中的一“页”&#xff0c;通常是…

钓鱼圈子钓点钓场鱼漂钓位小程序开发

钓鱼圈子钓点钓场鱼漂钓位小程序开发 功能: 关注好友功能。一键导航至钓鱼点。学习交流。鱼票功能是本系统的—大亮点&#xff0c;此功能可应用于鱼场举办活动比赛以及日常预定位置&#xff0c;在小程序进行预定&#xff0c;线下核销。系统拥有商城功能&#xff0c;可以为运营…

深度学习环境配置系列文章(三):配置VS Code和Jupyter的Python环境

深度学习环境配置系列文章目录 第一章 专业名称和配置方案介绍 第二章 Anaconda配置Python和PyTorch 第三章 配置VS Code和Jupyter的Python环境 第四章 配置Windows11和Linux双系统 第五章 配置Docker深度学习开发环境 第三章文章目录 深度学习环境配置系列文章目录前言一、VS…

C语言中链表经典面试题目——复制带随机指针的链表

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练&#xff0c;题解C&#xff0c;C的使用文章&#xff0c;「初学」C&#xff0c;数据结构​​​​​​​ &#x1f525;座右铭&#xff1a;“不…

计算机数据表示和数据转换

1、计算机数据表示和数据转换 送入计算机的数字、字母和符号等信息必须转换成0、1组合的二进制形式形式才能被计算机所接收、存储和运算。能够进行计算的数据并且能得出一个明确的数值叫数值数据&#xff0c;其余信息是非数值数据。 1.1 数值数据的表示 数值数据的计数方式是进…