Mind and Hand Help

Access Control

整体逻辑 :基于 group_ip 获取规则组,白名单或黑名单的模式匹配请求上下文,获取访问控制结果

规则管理器 manager模块化提供 ,匹配时提供核心方法

  • function get_rules(group_id) :基于 group_id 获取的规则列表方法

  • function get_value_func(rule): 基于 rule 自生获取对应的 function

    • 设计的 operatorfunction 时,会寻找规则中的 方法规则进行匹配

    • 方法规则的设计目的是为了,对于规则中无法通过简单的字符串匹配的场景,实现更复杂的匹配

  • function get_internal_function(rule): 基于 rule 自生获取对应的内置 function

    • 设计的 operator@function 时,会寻找规则中的 内置方法规则进行匹配

    • 内置方法规则的设计目的是为了,提供一些常用的匹配方法,方便用户直接使用

local _M = {} local ac_utils = require("lua_modules.http_req.access_control.ac_utils") -- 匹配规则 -- @param field_val 字段值 -- @param operator 操作符 -- @param value 规则值 -- @param rule 规则本身,可以适配更多复杂场景 -- @param manager 可选的存储对象,默认为 rules_manager -- @return boolean 是否匹配 local function match_rule(field_val, operator, value, rule, manager) if not field_val or not operator then return false end -- 方法,获取方法函数 if operator == "function" then -- 获取计算值的函数 local value_func, err = ac_utils.get_value_func(rule, manager) if not value_func then ngx.log(ngx.ERR, "failed to get function rule: ", err or "unknown error") return false end if type(value_func) ~= "function" then ngx.log(ngx.ERR, "value_func must be a function when operator is 'function'") return false end -- 调用函数并确保返回布尔值 local ok, res = pcall(value_func, field_val) if not ok then return false end if type(res) ~= "boolean" then return false end return res end -- 方法,获取内置的方法 if operator == "@function" then local func, err = ac_utils.get_internal_function(rule, manager) if not func then ngx.log(ngx.ERR, "failed to get function: ", err or "unknown error") return false end if type(func) ~= "function" then ngx.log(ngx.ERR, "func must be a function when operator is '@function'") return false end -- 调用函数并确保返回布尔值 local ok, res = pcall(func, field_val) if not ok then return false end if type(res) ~= "boolean" then return false end return res end --一些通用的操作符 if operator == "equals" then return field_val == value elseif operator == "not_equals" then return field_val ~= value elseif operator == "prefix" then return field_val:sub(1, #value) == value elseif operator == "suffix" then return field_val:sub(-#value) == value elseif operator == "contains" then return field_val:find(value, 1, true) ~= nil elseif operator == "regex" then return ngx.re.find(field_val, value, "jo") ~= nil elseif operator == "in" then -- 支持逗号分隔字符串或 table if type(value) == "string" then for v in value:gmatch("[^,]+") do if field_val == v then return true end end elseif type(value) == "table" then for _, v in ipairs(value) do if field_val == v then return true end end end return false else -- 未知操作符 return false end end -- 核心检查函数 -- 白名单检查是只要有一条规则命中就放行 -- 黑名单检查是只要有一条规则命中就拒绝 -- @param ctx 请求上下文 -- @param rules 规则列表 一个规则示例 {field="host", operator="equals", value="example.com", effect="deny"} -- @param mode 检查模式 "whitelist" 或 "blacklist" -- @param manager 可选的规则管理器,默认为 rules_manager -- @return boolean 是否允许通过 local function check_ctx(ctx, rules, mode, manager) mode = mode or "blacklist" for _, rule in ipairs(rules) do local field_val = ctx[rule.field] -- 获取指定字段的值 if field_val and match_rule(field_val, rule.operator, rule.value, rule, manager) then if mode == "blacklist" and rule.effect == "deny" then return false elseif mode == "whitelist" and rule.effect == "allow" then return true end end end -- 如果没有任何规则命中 if mode == "blacklist" then return true -- 默认放行 else return false -- 默认拒绝 end end -- 通用检查函数 -- @param ctx 请求上下文 -- @param rules 规则列表 -- @param mode 检查模式 "whitelist" 或 "blacklist" -- @param manager 可选的规则管理器,默认为 rules_manager -- @return boolean 是否允许通过 function _M.check_ctx(ctx, rules, mode, manager) return check_ctx(ctx, rules, mode, manager) end -- 白名单检查 -- 只要有一条规则命中就放行 -- @param ctx 请求上下文 -- @param rules 规则列表 -- @param manager 可选的规则管理器,默认为 rules_manager -- @return boolean 是否允许通过 function _M.check_ctx_whitelist(ctx, rules, manager) return check_ctx(ctx, rules, "whitelist", manager) end -- 黑名单检查 -- 只要有一条规则命中就拒绝 -- @param ctx 请求上下文 -- @param rules 规则列表 -- @param manager 可选的规则管理器,默认为 rules_manager -- @return boolean 是否允许通过 function _M.check_ctx_blacklist(ctx, rules, manager) return check_ctx(ctx, rules, "blacklist", manager) end return _M
27 January 2026