Sentinel——授权规则
授权规则
授权规则是一种通过对请求来源进行甄别的鉴权规则。规则规定了哪些请求可以通过访问,而哪些请求则是被拒绝访问的。而这些请求的设置是通过黑白名单来完成的。
无论是黑名单还是白名单,其实就是一个请求来源名称列表。出现在来源黑名单中的请求将被拒绝访问,而其它来源的请求则可以正常访问;出现在来源白名单中的请求是可以正常访问的,而其它来源的请求则将被拒绝。
controller
package com.zjw.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.zjw.domain.Depart;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
/**
* <p>
* 部门表 前端控制器
* </p>
*
* @since 2023-11-20
*/
@RestController
@RequestMapping("/depart")
@Slf4j
public class DepartController {
@Resource
private RestTemplate restTemplate;
private static final String PROVIDER_URL = "http://depart-provider/depart";
/**
* 根据id查询部门
*/
//发生异常会降级,调用getFallBack方法, 触发流控,会调用流控的getFlowFallBack方法
@SentinelResource(value = "get", fallback = "getFallBack", blockHandler = "getFlowFallBack")
@GetMapping("/get/{id}")
public Depart get(@PathVariable Long id) {
return restTemplate.getForObject(PROVIDER_URL + "/get/" + id, Depart.class);
}
/**
* 服务流控使用的方法.
* 需要指定BlockException参数,否则调用降级方法
*/
public Depart getFlowFallBack(Long id, BlockException e) {
log.info("id = " + id);
log.info("exception = " + e.getMessage());
Depart depart = new Depart();
depart.setId(id);
depart.setName("flow fall back");
return depart;
}
/**
* 服务降级使用的方法
*/
public Depart getFallBack(Long id, Throwable t) {
log.info("id = " + id);
log.info("throwable = " + t.getMessage());
Depart depart = new Depart();
depart.setId(id);
depart.setName("no this depart");
return depart;
}
/**
* 查询所有部门
*/
@SuppressWarnings("unchecked")
@SentinelResource(value = "list")
@GetMapping("/list")
public List<Depart> list() {
return (List<Depart>)restTemplate.getForObject(PROVIDER_URL + "/list", List.class);
}
}
解析请求来源
package com.zjw.parser;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
/**
* 解析请求来源
* @since 2023/12/04 18:33
*/
@Component
@Slf4j
public class DepartRequestOriginParser implements RequestOriginParser {
@Override
public String parseOrigin(HttpServletRequest request) {
String source = request.getParameter("source");
if(!StringUtils.hasText(source)){
//设置为默认来源
source = "guest";
}
log.info("source = " + source);
return source;
}
}
控制台设置规则
sentinel控制台设置授权规则
当请求来源为vip
,1
,2
的进行放行。
API设置规则
package com.zjw;
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.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.ArrayList;
import java.util.List;
@SpringBootApplication
public class ConsumerAuthRule8080Application {
public static void main(String[] args) {
SpringApplication.run(ConsumerAuthRule8080Application.class, args);
//初始化授权规则
initRule();
}
private static void initRule() {
AuthorityRuleManager.loadRules(configAuthRule());
}
// 设置授权规则
private static List<AuthorityRule> configAuthRule() {
List<AuthorityRule> ruleList = new ArrayList<>();
AuthorityRule rule = new AuthorityRule();
// 资源名
rule.setResource("get");
// 针对来源
rule.setLimitApp("vip,1,2");
// 设置白名单
rule.setStrategy(RuleConstant.AUTHORITY_WHITE);
ruleList.add(rule);
return ruleList;
}
}
效果和在sentinel控制台设置的一样。
---------------
我每一次回头,都感觉自己不够努力,所以我不再回头。
---------------