很多时候,我们需要根据调用来源来判断该次请求是否允许放行,这时候可以使用 Sentinel 的来源访问控制(黑白名单控制)的功能。来源访问控制根据资源的请求来源(origin)判断资源访问是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。
1 重要的属性
来源访问控制规则(AuthorityRule)非常简单,主要有以下配置项:
- resource :资源名,即限流规则的作用对象。
- limitApp :请求来源,对应的黑名单/白名单,多个用","分隔,如 appA,appB。
- strategy :限制模式,AUTHORITY_WHITE为白名单模式,AUTHORITY_BLACK为黑名单模式,默认为白名单模式。
这里演示实现Ip地址白名单和黑名单配置规则
2 实现步骤
授权控制规则设置有两种方式
- 本地代码设置
- 在Sentinel控制台动态设置
3 本地代码设置
1.创建WhiteBlackController,在其中编写修改以下代码
package com.example.demo.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
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 org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
@RestController
public class WhiteBlackController {
//定义限流资源和限流讲解回调函数
@SentinelResource(value = "Sentinel_Rule", blockHandler = "exceptionHandler")
@GetMapping("origin")
public String hello() {
return "Hello Sentinel!";
}
// blockHandler函数,原方法调用被限流/降级/系统保护的时候调用
public String exceptionHandler(BlockException ex) {
ex.printStackTrace();
return "系统繁忙,请稍候";
}
/**
* 白名单设置
*
* @PostConstruct :在构造函数执行完毕后执行
*/
@PostConstruct
private static void initWhiteRules() {
//1.创建存放授权规则的集合
List<AuthorityRule> rules = new ArrayList<AuthorityRule>();
//2.创建授权规则
AuthorityRule rule = new AuthorityRule();
//定义资源
rule.setResource("Sentinel_Rule");
//设置授权模式 RuleConstant.AUTHORITY_WHITE :白名单
rule.setStrategy(RuleConstant.AUTHORITY_WHITE);
//设置白名单
rule.setLimitApp("192.168.1.3");
//将授权规则添加到集合中
rules.add(rule);
//3.加载授权规则
AuthorityRuleManager.loadRules(rules);
}
/**
* 黑名单设置
*
* @PostConstruct :在构造函数执行完毕后执行
*/
@PostConstruct
private static void initBlackRules() {
//1.创建存放授权规则的集合
List<AuthorityRule> rules = new ArrayList<AuthorityRule>();
//2.创建授权规则
AuthorityRule rule = new AuthorityRule();
//定义资源
rule.setResource("Sentinel_Rule");
//设置授权模式 RuleConstant.AUTHORITY_BLACK :黑名单
rule.setStrategy(RuleConstant.AUTHORITY_BLACK);
//设置黑名单
rule.setLimitApp("127.0.0.1");
//将授权规则添加到集合中
rules.add(rule);
//3.加载授权规则
AuthorityRuleManager.loadRules(rules);
}
}
白名单和黑名单只要配置一个就可以满足需求。
2.创建SentinelConfig,设置请求来源解析
package com.example.demo.config;
import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser;
import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
@Component
public class SentinelConfig {
@PostConstruct
public void init(){
//获取请求来源ip地址
WebCallbackManager.setRequestOriginParser(new RequestOriginParser() {
@Override
public String parseOrigin(HttpServletRequest httpServletRequest) {
return httpServletRequest.getRemoteAddr();
}
});
}
}
3.运行测试
通过浏览器输入http://192.168.1.3:8080/origin进行访问,则显示”Hello Sentinel”;当浏览器输入http://127.0.0.1:8080/origin,则显示”系统繁忙,请稍候”,这说明授权控制规则设置成功。
4 在Sentinel控制台动态设置
将WhiteBlackController中的代码设置授权控制规则删除,重启项目,在Sentinel控制台动态设置授权控制规则。
在Sentinel控制台的左侧菜单中选择“授权规则”,点击“新增授权规则”按钮,增加白名单或者黑名单。只用设置一个即可,设置白名单,则白名单以外的皆为黑名单,设置黑名单,则黑名单以外的都是白名单。
白名单如下:
黑名单如下:
之后,通过浏览器输入http://192.168.1.3:8080/origin进行访问,则显示”Hello Sentinel”;当浏览器输入http://127.0.0.1:8080/origin,则显示”系统繁忙,请稍候”,这说明授权控制规