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控制台设置的一样。

posted @ 2023-12-04 19:29  雨中遐想  阅读(123)  评论(0编辑  收藏  举报