|
@@ -6,23 +6,20 @@ import java.util.List;
|
|
|
import java.util.Objects;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
-import com.chelvc.framework.base.context.ApplicationContextHolder;
|
|
|
import com.chelvc.framework.base.context.ThreadContextHolder;
|
|
|
-import com.chelvc.framework.base.logic.ContextVariableParser;
|
|
|
import com.chelvc.framework.base.logic.VariableParser;
|
|
|
-import com.chelvc.framework.common.exception.FrameworkException;
|
|
|
import com.chelvc.framework.common.model.Pair;
|
|
|
import com.chelvc.framework.common.util.IdentityUtils;
|
|
|
import com.chelvc.framework.common.util.ObjectUtils;
|
|
|
import com.chelvc.framework.common.util.StringUtils;
|
|
|
import com.chelvc.framework.redis.context.RedisContextHolder;
|
|
|
import com.google.common.collect.Lists;
|
|
|
+import lombok.NonNull;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.dao.DataAccessException;
|
|
|
import org.springframework.data.redis.core.RedisOperations;
|
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
|
import org.springframework.data.redis.core.SessionCallback;
|
|
|
-import org.springframework.http.HttpStatus;
|
|
|
|
|
|
/**
|
|
|
* 防火墙处理器默认实现
|
|
@@ -32,14 +29,21 @@ import org.springframework.http.HttpStatus;
|
|
|
*/
|
|
|
@Slf4j
|
|
|
public class DefaultFirewallProcessor implements FirewallProcessor {
|
|
|
+ private final VariableParser parser;
|
|
|
+ private final List<Action> actions;
|
|
|
private volatile IdentityUtils.Generator sequenceGenerator;
|
|
|
|
|
|
+ public DefaultFirewallProcessor(@NonNull VariableParser parser, @NonNull List<Action> actions) {
|
|
|
+ this.parser = parser;
|
|
|
+ this.actions = Collections.unmodifiableList(actions);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 获取序列号
|
|
|
*
|
|
|
* @return 序列号数字
|
|
|
*/
|
|
|
- protected Long getSequence() {
|
|
|
+ private Long getSequence() {
|
|
|
if (this.sequenceGenerator == null) {
|
|
|
synchronized (this) {
|
|
|
if (this.sequenceGenerator == null) {
|
|
@@ -51,26 +55,16 @@ public class DefaultFirewallProcessor implements FirewallProcessor {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 获取变量解析器
|
|
|
- *
|
|
|
- * @return 变量解析器实例
|
|
|
- */
|
|
|
- protected VariableParser getVariableParser() {
|
|
|
- return ContextVariableParser.getInstance();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 执行规则动作处理
|
|
|
+ * 处理规则动作
|
|
|
*
|
|
|
* @param principal 主体信息
|
|
|
* @param rule 匹配规则
|
|
|
*/
|
|
|
- protected void doAction(String principal, Rule rule) {
|
|
|
- if (Objects.equals(rule.getAction(), "OBSERVE")) {
|
|
|
- log.warn("Firewall rule triggered: {}, principal: {}", rule.getId(), principal);
|
|
|
- } else if (Objects.equals(rule.getAction(), "INTERCEPT")) {
|
|
|
- throw new FrameworkException(HttpStatus.FORBIDDEN.name(), null,
|
|
|
- ApplicationContextHolder.getMessage("Forbidden"));
|
|
|
+ private void doAction(String principal, Rule rule) {
|
|
|
+ for (Action action : this.actions) {
|
|
|
+ if (Objects.equals(rule.getAction(), action.getName())) {
|
|
|
+ action.execute(principal, rule);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -81,12 +75,11 @@ public class DefaultFirewallProcessor implements FirewallProcessor {
|
|
|
* @return 主体/规则列表
|
|
|
*/
|
|
|
private List<Pair<String, Rule>> getMatchRules(List<Rule> rules) {
|
|
|
- VariableParser parser = this.getVariableParser();
|
|
|
List<Pair<String, Rule>> matches = Lists.newLinkedList();
|
|
|
for (Rule rule : rules) {
|
|
|
CharSequence principal = null;
|
|
|
- if (rule.getCondition().eval(parser) && (rule.getCount() < 1
|
|
|
- || StringUtils.notEmpty(principal = rule.getPrincipal().parse(parser)))) {
|
|
|
+ if (rule.getCondition().eval(this.parser) && (rule.getCount() < 1
|
|
|
+ || StringUtils.notEmpty(principal = rule.getPrincipal().parse(this.parser)))) {
|
|
|
matches.add(Pair.of(StringUtils.toString(principal), rule));
|
|
|
}
|
|
|
}
|
|
@@ -99,7 +92,7 @@ public class DefaultFirewallProcessor implements FirewallProcessor {
|
|
|
* @param pairs 主体/规则列表
|
|
|
* @return 动作列表
|
|
|
*/
|
|
|
- private List<String> getAccessControls(List<Pair<String, Rule>> pairs) {
|
|
|
+ protected List<String> getAccessControls(List<Pair<String, Rule>> pairs) {
|
|
|
List<String> keys = Lists.newArrayListWithCapacity(pairs.size());
|
|
|
pairs.forEach(pair -> keys.add("acl:" + pair.getKey() + ":" + pair.getValue().getId()));
|
|
|
RedisTemplate<String, String> template = RedisContextHolder.getDefaultTemplate();
|
|
@@ -111,7 +104,7 @@ public class DefaultFirewallProcessor implements FirewallProcessor {
|
|
|
*
|
|
|
* @param pairs 主体/规则列表
|
|
|
*/
|
|
|
- private void refreshAccessControls(List<Pair<String, Rule>> pairs) {
|
|
|
+ protected void refreshAccessControls(List<Pair<String, Rule>> pairs) {
|
|
|
// 批量刷新时间窗口数据
|
|
|
Long sequence = this.getSequence(), timestamp = System.currentTimeMillis();
|
|
|
RedisTemplate<String, Object> template = RedisContextHolder.getDefaultTemplate();
|