当前位置: 首页 > news >正文

Sentinel架构篇 - 来源访问控制

来源访问控制(黑白名单)

概念

Sentinel 提供了黑白名单限制资源能否通过的功能。如果配置了白名单,则只有位于白名单的请求来源的对应的请求才能通过;如果配置了黑名单,则位于黑名单的请求来源对应的请求不能通过。

实际操作

在这里插入图片描述

在 Nacos 控制台的配置管理/配置列表中,在 public 的命名空间中创建一个如下配置:

dataId:spring-cloud-demo-provider-sentinel-authority

group:DEFAULT_GROUP

配置内容如下:

[{"resource": "/hello","limitApp": "white-origin","strategy": 0},{"resource": "/hello/say","limitApp": "black-origin","strategy": 1}
]

strategy 为 0 表示白名单;为 1 表示黑名单。

limitApp 如果有多个请求来源,则使用逗号分隔。


对应的客户端的配置文件如下:

spring:application:name: spring-cloud-demo-providercloud:nacos:discovery:server-addr: 10.211.55.11:8848,10.211.55.12:8848,10.211.55.13:8848enabled: truesentinel:transport:dashboard: 127.0.0.1:9000eager: trueweb-context-unify: falsedatasource:authority-nacos-datasource:nacos:server-addr: 10.211.55.11:8848,10.211.55.12:8848,10.211.55.13:8848group-id: DEFAULT_GROUPnamespace: publicdata-id: ${spring.application.name}-sentinel-authoritydata-type: jsonrule-type: authorityusername: nacospassword: nacos

然后注册一个 RequestOriginParser 类型的 Bean。

@Component
public class MyRequestOriginParser implements RequestOriginParser {@Overridepublic String parseOrigin(HttpServletRequest httpServletRequest) {String origin = httpServletRequest.getHeader("origin");if (StringUtils.isBlank(origin)) {origin = "default";}return origin;}
}

请求时,在请求头添加一对 origin, whiteOrigin 或者 origin, blackOrigin 就能看到黑白名单对于特定资源的限制效果了。

实际操作中,个人发现如果被黑白名单限制的话,程序不会抛出异常,而是响应中输出 Blocked by Sentinel (flow limiting)。

AuthoritySlot

负责对请求来源的授权规则进行校验。

@Spi(order = Constants.ORDER_AUTHORITY_SLOT)
public class AuthoritySlot extends AbstractLinkedProcessorSlot<DefaultNode> {@Overridepublic void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count, boolean prioritized, Object... args)throws Throwable {// 校验请求来源的授权规则checkBlackWhiteAuthority(resourceWrapper, context);// 交给下一个ProcessorSlot继续处理fireEntry(context, resourceWrapper, node, count, prioritized, args);}@Overridepublic void exit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) {// 交给下一个ProcessorSlot继续处理fireExit(context, resourceWrapper, count, args);}void checkBlackWhiteAuthority(ResourceWrapper resource, Context context) throws AuthorityException {// 加载所有资源的授权规则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)) {throw new AuthorityException(context.getOrigin(), rule);}}}
}

接下来看下 AuthorityRuleChecker 的 passCheck 方法的内部逻辑。

static boolean passCheck(AuthorityRule rule, Context context) {// 获取上下文记录的请求来源String requester = context.getOrigin();// 如果请求来源为空或者授权规则的limitApp为空,则返回true,表示校验通过if (StringUtil.isEmpty(requester) || StringUtil.isEmpty(rule.getLimitApp())) {return true;}// 判断授权规则的limitApp中是否存在指定的请求来源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();// 如果设置了黑名单,并且授权规则中包含指定的请求来源,则返回false,表示校验不通过if (strategy == RuleConstant.AUTHORITY_BLACK && contain) {return false;}// 如果设置了白名单,并且授权规则中不包含指定的请求来源,则返回false,表示校验不通过if (strategy == RuleConstant.AUTHORITY_WHITE && !contain) {return false;}// 其余请求,返回true,表示校验通过return true;
}
http://www.lryc.cn/news/34494.html

相关文章:

  • 多线程的Thread 类及方法
  • QT入门Item Views之QTreeView
  • Servlet | Servlet简单入门——构建第一个Servlet项目
  • Spring的IOC/DI,依赖注入的实现
  • 【tensorflow onnx】TensorFlow2导出ONNX及模型可视化教程
  • 天梯赛训练L1-013--L1-015
  • 进程(操作系统408)
  • 浅谈运维工程师的开发能力的培养
  • Netcode升级到1.2.0网络变量的变化的变化
  • 冥想第七百二十二天
  • AB测试——流程介绍(定义问题和指标选取)
  • Linux(Centos)安装Minio集群
  • LeetCode 1662. 检查两个字符串数组是否相等 / 795. 区间子数组个数 / 剑指 Offer 47. 礼物的最大价值
  • 【C++】缺省参数函数重载
  • Hbuilder 下载与安装教程
  • Mybatis工程升级到FlunetMybatis后引发的问题以及解决方法
  • Oracle VM VirtualBox6.1.36导入ova虚拟机文件报错,代码: E_INVALIDARG (0x80070057)
  • Superset数据探索和可视化平台入门以及案例实操
  • VisualSP Enterprise - February crack
  • 004+limou+HTML——(4)HTML表格
  • uniapp实现自定义相机
  • 插值多项式的龙格现象的介绍与模拟
  • Spring整体架构包含哪些组件?
  • 开发接口需要考虑哪些问题?
  • 关于Activiti7审批工作流绘画流程图(2)
  • String.format()对日期进行格式化
  • 核酸检测信息管理系统
  • 典型回溯题目 - 全排列(一、二)
  • 数据清洗和特征选择
  • java StringBuilder 和 StringBuffer 万字详解(深度讲解)