博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
聊聊sentinel的AuthoritySlot
阅读量:7065 次
发布时间:2019-06-28

本文共 7361 字,大约阅读时间需要 24 分钟。

  hot3.png

本文主要研究一下sentinel的AuthoritySlot

AuthoritySlot

com/alibaba/csp/sentinel/slots/block/authority/AuthoritySlot.java

public class AuthoritySlot extends AbstractLinkedProcessorSlot
{ @Override public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count, Object... args) throws Throwable { AuthorityRuleManager.checkAuthority(resourceWrapper, context, node, count); fireEntry(context, resourceWrapper, node, count, args); } @Override public void exit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) { fireExit(context, resourceWrapper, count, args); }}
  • 这里执行AuthorityRuleManager.checkAuthority进行校验

AuthorityRuleManager

com/alibaba/csp/sentinel/slots/block/authority/AuthorityRuleManager.java

public class AuthorityRuleManager {    private static Map
> authorityRules = new ConcurrentHashMap
>(); final static RulePropertyListener listener = new RulePropertyListener(); private static SentinelProperty
> currentProperty = new DynamicSentinelProperty
>(); static { currentProperty.addListener(listener); } public static void register2Property(SentinelProperty
> property) { synchronized (listener) { if (currentProperty != null) { currentProperty.removeListener(listener); } property.addListener(listener); currentProperty = property; } } /** * Load the authority rules to memory. * * @param rules list of authority rules */ public static void loadRules(List
rules) { currentProperty.updateValue(rules); } public static void checkAuthority(ResourceWrapper resource, Context context, DefaultNode node, int count) throws BlockException { if (authorityRules == null) { return; } List
rules = authorityRules.get(resource.getName()); if (rules == null) { return; } for (AuthorityRule rule : rules) { if (!rule.passCheck(context, node, count)) { throw new AuthorityException(context.getOrigin()); } } } public static boolean hasConfig(String resource) { return authorityRules.containsKey(resource); } /** * Get a copy of the rules. * * @return a new copy of the rules. */ public static List
getRules() { List
rules = new ArrayList
(); if (authorityRules == null) { return rules; } for (Map.Entry
> entry : authorityRules.entrySet()) { rules.addAll(entry.getValue()); } return rules; } private static class RulePropertyListener implements PropertyListener
> { @Override public void configUpdate(List
conf) { Map
> rules = loadAuthorityConf(conf); authorityRules.clear(); if (rules != null) { authorityRules.putAll(rules); } RecordLog.info("[AuthorityRuleManager] Authority rules received: " + authorityRules); } private Map
> loadAuthorityConf(List
list) { if (list == null) { return null; } Map
> newRuleMap = new ConcurrentHashMap
>(); for (AuthorityRule rule : list) { if (StringUtil.isBlank(rule.getLimitApp())) { rule.setLimitApp(FlowRule.LIMIT_APP_DEFAULT); } String identity = rule.getResource(); List
ruleM = newRuleMap.get(identity); // putIfAbsent if (ruleM == null) { ruleM = new ArrayList
(); ruleM.add(rule); newRuleMap.put(identity, ruleM); } else { // One resource should only have at most one authority rule, so just ignore redundant rules. RecordLog.warn("[AuthorityRuleManager] Ignoring redundant rule: " + rule.toString()); } } return newRuleMap; } @Override public void configLoad(List
value) { Map
> rules = loadAuthorityConf(value); authorityRules.clear(); if (rules != null) { authorityRules.putAll(rules); } RecordLog.info("[AuthorityRuleManager] Load authority rules: " + authorityRules); } }}
  • checkAuthority方法从authorityRules中获取对应资源的规则,之后挨个进行rule.passCheck校验

AuthorityRule

com/alibaba/csp/sentinel/slots/block/authority/AuthorityRule.java

public class AuthorityRule extends AbstractRule {    /**     * Mode: 0 for whitelist; 1 for blacklist.     */    private int strategy = RuleConstant.AUTHORITY_WHITE;    public int getStrategy() {        return strategy;    }    public void setStrategy(int strategy) {        this.strategy = strategy;    }    @Override    public boolean equals(Object o) {        if (this == o) { return true; }        if (!(o instanceof AuthorityRule)) { return false; }        if (!super.equals(o)) { return false; }        AuthorityRule rule = (AuthorityRule)o;        return strategy == rule.strategy;    }    @Override    public int hashCode() {        int result = super.hashCode();        result = 31 * result + strategy;        return result;    }    @Override    public boolean passCheck(Context context, DefaultNode node, int count, Object... args) {        String requester = context.getOrigin();        // Empty origin or empty limitApp will pass.        if (StringUtil.isEmpty(requester) || StringUtil.isEmpty(this.getLimitApp())) {            return true;        }        // Do exact match with origin name.        int pos = this.getLimitApp().indexOf(requester);        boolean contain = pos > -1;        if (contain) {            boolean exactlyMatch = false;            String[] appArray = this.getLimitApp().split(",");            for (String app : appArray) {                if (requester.equals(app)) {                    exactlyMatch = true;                    break;                }            }            contain = exactlyMatch;        }        if (strategy == RuleConstant.AUTHORITY_BLACK && contain) {            return false;        }        if (strategy == RuleConstant.AUTHORITY_WHITE && !contain) {            return false;        }        return true;    }    @Override    public String toString() {        return "AuthorityRule{" +            "resource=" + getResource() +            ", limitApp=" + getLimitApp() +            ", strategy=" + strategy +            "} ";    }}
  • passCheck方法通过context的origin跟limitApp进行匹配

CommonFilter

com/alibaba/csp/sentinel/adapter/servlet/CommonFilter.java

public class CommonFilter implements Filter {    @Override    public void init(FilterConfig filterConfig) {    }    @Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)        throws IOException, ServletException {        HttpServletRequest sRequest = (HttpServletRequest)request;        Entry entry = null;        try {            String target = FilterUtil.filterTarget(sRequest);            target = WebCallbackManager.getUrlCleaner().clean(target);            ContextUtil.enter(target);            entry = SphU.entry(target, EntryType.IN);            chain.doFilter(request, response);        } catch (BlockException e) {            HttpServletResponse sResponse = (HttpServletResponse)response;            WebCallbackManager.getUrlBlockHandler().blocked(sRequest, sResponse);        } catch (IOException e2) {            Tracer.trace(e2);            throw e2;        } catch (ServletException e3) {            Tracer.trace(e3);            throw e3;        } catch (RuntimeException e4) {            Tracer.trace(e4);            throw e4;        } finally {            if (entry != null) {                entry.exit();            }            ContextUtil.exit();        }    }    @Override    public void destroy() {    }}
  • 目前基于servlet的CommonFilter,在调用ContextUtil.enter(target)的时候,并没有指定origin,目前默认为""

小结

AuthoritySlot主要用来做黑白名单的匹配,现在还不是很完善,origin在CommonFilter进入entry时没有指定。

doc

转载于:https://my.oschina.net/go4it/blog/1933315

你可能感兴趣的文章
Powershell 比较AD和Exchange的用户登录时间
查看>>
系统出现非法操作错误解决对策
查看>>
xml文件对比或xml大字符串对比方法(蛮精简的)
查看>>
Weblogic产品模式切换与JVM切换
查看>>
论“性能需求分析”系列专题(一)之 性能需求剖析
查看>>
费波拉奇 递归
查看>>
PC 加入AD域的要求
查看>>
Enterprise Library 2.0 Hands On Lab 翻译(1):数据访问程序块(一)
查看>>
微软私有云分享(R2)17SCAC被精简的功能
查看>>
安装maildrop-2.0.4
查看>>
Spring Security身份认证之HelloSpringSecurity(附源码)
查看>>
WPF实例秀——不用属性也Binding
查看>>
打造Ubuntu下的SLAMP
查看>>
系统初始化SHELL脚本
查看>>
用”伪代码“装饰你的程序
查看>>
Windows 2008R2平台: Exchange 2010安装部署笔记(一)
查看>>
利用XMPP协议推送服务器告警信息到安卓平台及桌面
查看>>
SoapUI实践:自动化测试、压力测试、持续集成
查看>>
Redis中Value使用hash类型的效率是普通String的两倍
查看>>
爪哇国新游记之八----读写文件及数组排序
查看>>