莲都区建设局门户网站,免费h5,中企动力企业邮箱手机登录,app代理推广合作50元来源访问控制#xff08;黑白名单#xff09;
概念
Sentinel 提供了黑白名单限制资源能否通过的功能。如果配置了白名单#xff0c;则只有位于白名单的请求来源的对应的请求才能通过#xff1b;如果配置了黑名单#xff0c;则位于黑名单的请求来源对应的请求不能通过。 …来源访问控制黑白名单
概念
Sentinel 提供了黑白名单限制资源能否通过的功能。如果配置了白名单则只有位于白名单的请求来源的对应的请求才能通过如果配置了黑名单则位于黑名单的请求来源对应的请求不能通过。
实际操作 在 Nacos 控制台的配置管理/配置列表中在 public 的命名空间中创建一个如下配置
dataIdspring-cloud-demo-provider-sentinel-authority
groupDEFAULT_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 AbstractLinkedProcessorSlotDefaultNode {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 {// 加载所有资源的授权规则MapString, SetAuthorityRule authorityRules AuthorityRuleManager.getAuthorityRules();// 如果授权规则列表为空则直接返回if (authorityRules null) {return;}// 获取指定资源的授权规则列表SetAuthorityRule 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;
}