风控流程

下单前进行风控校验

 // 1.begin---风控处理---前置处理{黑白名单校验}
RiskControlRuleEnum controlRuleEnum = riskControlHandlerService.preHandle(mappingObj.getMerchantGoodsType(), thatUser);
if (controlRuleEnum != null) {
logger.error("风控处理进入--->{}", controlRuleEnum.getDesc());
Result error = Result.error(controlRuleEnum.getDesc());
error.setCode("WEB_RISK_CONTROL_" + controlRuleEnum.getCode());
return error;
}

下单后进行风控判断是否会进入

  // 2.ending---风控限制后置处理|处理{黑白名单校验}
taskExecutor.execute(() -> riskControlHandlerService.afterBuyingTicketsHandle(mappingObj.getMerchantGoodsType(), user));

风控前置校验

    /**
* 风控---前置校验
*
* @param user user
* @return
* @throws Exception
*/
public RiskControlRuleEnum preHandle(String merchantGoodsType, User user) {
// 风控规则校验---拒绝购买票的号码校验
List<RiskControlManager> managerList = riskControlManagerService.getByMerchantGoodsType(merchantGoodsType);
if (CollectionUtils.isNotEmpty(managerList)) {
for (RiskControlManager manager : managerList) {
// 拒绝号码购买----风控校验
String riskControlDesc = manager.getRiskControlDesc();
if (StringUtils.isNotBlank(riskControlDesc)) {
String[] splitPhone = riskControlDesc.split(",");
for (String thatLimitPhone : splitPhone) {
if (StringUtils.isNotBlank(user.getMobile()) && user.getMobile().startsWith(thatLimitPhone)) {
return RiskControlRuleEnum.TicketPurchaseProhibited;
}
}
}
}
}
RiskControlUsers riskControlUsers = new RiskControlUsers();
riskControlUsers.setPayerId(user.getMid());
riskControlUsers.setMerchantGoodsType(merchantGoodsType);
List<RiskControlUsers> riskControlUsers1 = riskControlUsersService.listAll(riskControlUsers);
if (CollectionUtils.isEmpty(riskControlUsers1)) {
return null;
}
// 如果有黑名单限制--黑名单限制
for (RiskControlUsers controlUsers : riskControlUsers1) {
if (controlUsers.getRiskControlLimitType().equals(RiskControlRuleEnum.TicketPurchaseProhibited.getCode())) {
return RiskControlRuleEnum.TicketPurchaseProhibited;
}
}
// 如果没有黑名单限制--灰名单限制
Integer riskControlLimitType = riskControlUsers1.get(0).getRiskControlLimitType();
RiskControlRuleEnum[] values = RiskControlRuleEnum.values();
for (RiskControlRuleEnum ruleEnum : values) {
if (ruleEnum.getCode().equals(riskControlLimitType)) {
return ruleEnum;
}
}
return null;
}

风控后置--决策

 /**
* 风控----后置校验
*
* @param user user
* @return
* @throws Exception
*/
public void afterBuyingTicketsHandle(String merchantGoodsType, User user) {
// 商品维度的风控策略加载||已启用的加商品类型过滤+优先级排序
List<RiskControlManager> managerList = riskControlManagerService.getByMerchantGoodsType(merchantGoodsType);
if (CollectionUtils.isEmpty(managerList)) {
return;
}
RiskControlDecisionsFilterChain filterChain = RiskControlDecisionsFilterChain.getInstance();
// 获取用户风控信息{已经SQL的排序修改按照序列的--优先级排序}
for (RiskControlManager manager : managerList) {
Long mid = manager.getMid();
// 获取风控惩罚机制
RiskControlRestrictive riskControlRestrictive = new RiskControlRestrictive();
riskControlRestrictive.setRiskControlRuleId(mid);
List<RiskControlRestrictive> restrictives = riskControlRestrictiveService.listAll(riskControlRestrictive);
if (CollectionUtils.isEmpty(restrictives)) {
// 如果没有--风控策略
continue;
}
// 风控排序 -----最小条件满足优先{天--小时---分钟}
Comparator<RiskControlRestrictive> comparator = new Comparator<RiskControlRestrictive>() {
@Override
public int compare(RiskControlRestrictive o1, RiskControlRestrictive o2) {
// 时间间隔单位
Integer timeIntervalUnitV1 = o1.getTimeIntervalUnit();
Integer timeIntervalUnitV2 = o2.getTimeIntervalUnit();
return timeIntervalUnitV1 - timeIntervalUnitV2;
}
};
restrictives.sort(comparator);
// 校验用户风控策略满足条件{过滤器链路使用---用户封印{无法根据IP、身份证、电话号码封印}}
for (RiskControlRestrictive restrictive : restrictives) {
// 获取限制类型---下单的限定
if (restrictive.getOperationType().equals(RiskControlRestrictiveOperationEnum.PlaceAnOrder.getCode())) {
// 风控决策引擎--启动{决策目标风控行为:开启所有的风控链决策--使用 execute 方法}
boolean execute = filterChain.executeDefaultHandler(user, manager, restrictive, riskControlLimitAccountFilterChain);
if (execute) {
// 满足风控条件任意一项:黑白名单入库成功---------风控过滤链释放
return;
}
} else if (restrictive.getOperationType().equals(RiskControlRestrictiveOperationEnum.Refund.getCode())) {
// 获取限制类型---退款的限定--todo }
}
}
}

风控决策引擎管理--总线

/**
* packageName com.cztech.platform.transaction.common.riskControl
*
* @author GuoTong
* @version JDK 8
* @className RiskControlDecisionsFilterChain
* @date 2024/5/9
* @description 风控决策引擎
*/
public class RiskControlDecisionsFilterChain { private Logger log = LoggerFactory.getLogger(RiskControlDecisionsFilterChain.class); /**
* 标识===过滤器所属限制类型
* 子类必须重写
*
* @return int
*/
protected int getThisRestrictiveType() {
return 0;
} /**
* 风控决策过滤器链
*/
public static List<RiskControlDecisionsFilterChain> filterChains = new ArrayList<>(); private static RiskControlDecisionsFilterChain chain = null; public static RiskControlDecisionsFilterChain getInstance() {
if (chain == null) {
synchronized (RiskControlDecisionsFilterChain.class) {
if (chain == null) {
chain = new RiskControlDecisionsFilterChain();
}
}
}
return chain;
} /**
* 风控决策引擎执行入口
*
* @param user 用户ID
* @param manager 风控管理器
* @param restrictive 风控限制
* @author GuoTong
*/
public boolean execute(User user, RiskControlManager manager, RiskControlRestrictive restrictive) {
log.error("风控决策引擎执行-----进入执行---------");
for (RiskControlDecisionsFilterChain filterChain : filterChains) {
// 获取限制类型----只运行当前限制的决策事件
if (restrictive.getRestrictiveType().equals(filterChain.getThisRestrictiveType())) {
// 获取执行链路的结果
boolean respWasSuccess = filterChain.execute(user, manager, restrictive);
// 已经执行成功,则过滤器链终止
if (respWasSuccess) {
return true;
}
} }
log.error("风控决策引擎执行-----执行结束---------");
return false;
} protected int countRiskControlLimit(String startTime, String endTime, User user) {
return 0;
} /**
* 保存用户--进入限制桶
* 子类必须重写
*
* @param riskControlUsers riskControlUsers
*/
protected void saveLimitUser(RiskControlUsers riskControlUsers) {
} protected ReleaseTimeSetting getReleaseTimeSetting() {
return null;
} /**
* 限制名单限定--决策----通用业务逻辑
*
* @param user userId
* @param manager manager
* @param restrictive restrictive
*/
protected boolean executeDefaultHandler(User user, RiskControlManager manager, RiskControlRestrictive restrictive, RiskControlDecisionsFilterChain targetFilterChain) {
// 获取时间间隔
Long timeInterval = restrictive.getTimeInterval();
// 获取时间间隔单位
Integer timeIntervalUnit = restrictive.getTimeIntervalUnit();
// 获取限制次数
Long quantity = restrictive.getQuantity();
// 计算限制区间:当前时间 -- 开始时间
LocalDateTime now = LocalDateTime.now();
String endTime = LocalDateTimeUtil.format(now, RuleCommonUtils.YYYY_MM_DD_HH_MM_SS);
String startTime = null;
if (timeIntervalUnit.equals(RiskControlRestrictiveTimeEnum.Minute.getCode())) {
// 如果是分钟
startTime = LocalDateTimeUtil.format(now.minusMinutes(timeInterval), RuleCommonUtils.YYYY_MM_DD_HH_MM_SS);
} else if (timeIntervalUnit.equals(RiskControlRestrictiveTimeEnum.Hours.getCode())) {
// 如果是小时
startTime = LocalDateTimeUtil.format(now.minusHours(timeInterval), RuleCommonUtils.YYYY_MM_DD_HH_MM_SS);
} else {
// 天
startTime = LocalDateTimeUtil.format(now.minusDays(timeInterval), RuleCommonUtils.YYYY_MM_DD_HH_MM_SS);
}
// 查询当前情况下的下单数量
int thatOrderNum = targetFilterChain.countRiskControlLimit(startTime, endTime, user);
if (thatOrderNum >= quantity) {
log.error("用户{}在{}到{}期间下单次数超过限制次数{}", user.getMid(), startTime, endTime, quantity);
// 封印该用户--todo{惩罚机制}
RiskControlUsers riskControlUsers = new RiskControlUsers();
riskControlUsers.setStateId(1);
riskControlUsers.setCreateTime(new Date());
riskControlUsers.setMerchantGoodsType(manager.getMerchantGoodsType());
riskControlUsers.setRiskControlDetailLimit(manager.getRiskControlDetailLimit());
riskControlUsers.setRiskControlLimitType(manager.getRiskControlRule());
ReleaseTimeSetting releaseTimeSetting = targetFilterChain.getReleaseTimeSetting();
if (releaseTimeSetting != null) {
riskControlUsers.setReleaseTimeDay(releaseTimeSetting.getNowDay());
} else {
riskControlUsers.setReleaseTimeDay(7);
}
riskControlUsers.setRiskControlCardType("身份证");
riskControlUsers.setIdCard(user.getIdentityNumber());
// 黑名单|白名单
riskControlUsers.setRiskControlTypeName(manager.getRiskControlRestrictive());
riskControlUsers.setUserName(user.getName());
riskControlUsers.setPhone(user.getMobile());
riskControlUsers.setIpAddres(user.getLastLoginIP());
riskControlUsers.setLimitTime(new Date());
riskControlUsers.setDescLimit(manager.getRiskControlName());
riskControlUsers.setPayerId(user.getMid());
log.error("风控----管控---用户信息------>:" + JSONObject.toJSONString(riskControlUsers));
targetFilterChain.saveLimitUser(riskControlUsers);
return true;
}
return false;
} }

风控链----01风控决策引擎---限制账户

/**
* packageName com.cztech.platform.transaction.common.riskControl
*
* @author GuoTong
* @version JDK 8
* @className RiskControlDecisionsFilterChain
* @date 2024/5/9
* @description 风控决策引擎---限制账户
*/
@Component
public class RiskControlLimitAccountFilterChain extends RiskControlDecisionsFilterChain { private Logger log = LoggerFactory.getLogger(RiskControlLimitAccountFilterChain.class); @Autowired
private RiskControlUsersService riskControlUsersService; @Autowired
private OrderService orderService; /**
* 标识===过滤器所属限制类型
* @return int
*/
@Override
protected int getThisRestrictiveType() {
return RiskControlRestrictiveEnum.LimitAccount.getCode();
} /**
* 保存用户--进入限制桶
* 子类必须重写
* @param riskControlUsers riskControlUsers
*/
protected void saveLimitUser(RiskControlUsers riskControlUsers) {
riskControlUsersService.save(riskControlUsers);
} /**
* 构造函数---注册到过滤器链
*/
public RiskControlLimitAccountFilterChain() {
filterChains.add(this);
} /**
* 风控决策引擎执行入口--限制账户
*
* @param user, 用户ID
* @param manager 风控管理器
* @param restrictive 风控限制
* @author GuoTong
*/
@Override
public boolean execute(User user, RiskControlManager manager, RiskControlRestrictive restrictive) {
boolean restrictiveFlag = false;
try {
restrictiveFlag = super.executeDefaultHandler(user, manager, restrictive,this);
} catch (Exception e) {
log.error("RiskControlLimitAccountFilterChain execute error:", e);
}
return restrictiveFlag;
} @Override
protected int countRiskControlLimit(String startTime, String endTime, User user) {
return orderService.countRiskControlLimit(startTime, endTime, user.getMid());
} @Override
protected ReleaseTimeSetting getReleaseTimeSetting() {
return riskControlUsersService.selectReleaseTimeData();
} }

风控链----02风控决策引擎---限制身份证

/**
* packageName com.cztech.platform.transaction.common.riskControl
*
* @author GuoTong
* @version JDK 8
* @className RiskControlDecisionsFilterChain
* @date 2024/5/9
* @description 风控决策引擎---限制身份证
*/
@Component
public class RiskControlLimitIdCardFilterChain extends RiskControlDecisionsFilterChain { private Logger log = LoggerFactory.getLogger(RiskControlLimitIdCardFilterChain.class); @Autowired
private RiskControlUsersService riskControlUsersService; @Autowired
private OrderService orderService; /**
* 标识===过滤器所属限制类型
* @return int
*/
@Override
protected int getThisRestrictiveType() {
return RiskControlRestrictiveEnum.LimitIdCard.getCode();
} /**
* 构造函数---注册到过滤器链
*/
public RiskControlLimitIdCardFilterChain() {
filterChains.add(this);
} /**
* 风控决策引擎执行入口--限制身份证
*
* @param user, 用户ID
* @param manager 风控管理器
* @param restrictive 风控限制
* @author GuoTong
*/
@Override
public boolean execute(User user, RiskControlManager manager, RiskControlRestrictive restrictive) {
boolean restrictiveFlag = false;
try {
restrictiveFlag = super.executeDefaultHandler(user, manager, restrictive,this);
} catch (Exception e) {
log.error("RiskControlLimitAccountFilterChain execute error:", e);
}
return restrictiveFlag;
} @Override
protected int countRiskControlLimit(String startTime, String endTime, User user) {
String identityNumber = user.getIdentityNumber();
if (StringUtils.isBlank(identityNumber)) {
return 0;
}
return orderService.countRiskControlFiledLimit(startTime, endTime, identityNumber);
} /**
* 保存用户--进入限制桶
* 子类必须重写
* @param riskControlUsers riskControlUsers
*/
protected void saveLimitUser(RiskControlUsers riskControlUsers) {
riskControlUsersService.save(riskControlUsers);
} @Override
protected ReleaseTimeSetting getReleaseTimeSetting() {
return riskControlUsersService.selectReleaseTimeData();
} }

风控链----03风控决策引擎---限制账IP

/**
* packageName com.cztech.platform.transaction.common.riskControl
*
* @author GuoTong
* @version JDK 8
* @className RiskControlDecisionsFilterChain
* @date 2024/5/9
* @description 风控决策引擎---限制IP
*/
@Component
public class RiskControlLimitIpFilterChain extends RiskControlDecisionsFilterChain { private Logger log = LoggerFactory.getLogger(RiskControlLimitIpFilterChain.class); @Autowired
private RiskControlUsersService riskControlUsersService; @Autowired
private OrderService orderService; /**
* 构造函数---注册到过滤器链
*/
public RiskControlLimitIpFilterChain() {
filterChains.add(this);
}
/**
* 标识===过滤器所属限制类型
* @return int
*/
@Override
protected int getThisRestrictiveType() {
return RiskControlRestrictiveEnum.LimitIp.getCode();
} /**
* 风控决策引擎执行入口--限制IP
*
* @param user, 用户ID
* @param manager 风控管理器
* @param restrictive 风控限制
* @author GuoTong
*/
@Override
public boolean execute(User user, RiskControlManager manager, RiskControlRestrictive restrictive) {
boolean restrictiveFlag = false;
try {
restrictiveFlag = super.executeDefaultHandler(user, manager, restrictive,this);
} catch (Exception e) {
log.error("RiskControlLimitAccountFilterChain execute error:", e);
}
return restrictiveFlag;
} @Override
protected int countRiskControlLimit(String startTime, String endTime, User user) {
String lastLoginIP = user.getLastLoginIP();
if (StringUtils.isBlank(lastLoginIP)) {
return 0;
}
return orderService.countRiskControlIPLimit(startTime, endTime, lastLoginIP);
} /**
* 保存用户--进入限制桶
* 子类必须重写
* @param riskControlUsers riskControlUsers
*/
protected void saveLimitUser(RiskControlUsers riskControlUsers) {
riskControlUsersService.save(riskControlUsers);
}
@Override
protected ReleaseTimeSetting getReleaseTimeSetting() {
return riskControlUsersService.selectReleaseTimeData();
} }

风控链----04风控决策引擎---限制手机

/**
* packageName com.cztech.platform.transaction.common.riskControl
*
* @author GuoTong
* @version JDK 8
* @className RiskControlDecisionsFilterChain
* @date 2024/5/9
* @description 风控决策引擎---限制手机号
*/
@Component
public class RiskControlLimitPhoneFilterChain extends RiskControlDecisionsFilterChain { private Logger log = LoggerFactory.getLogger(RiskControlLimitPhoneFilterChain.class); @Autowired
private RiskControlUsersService riskControlUsersService; @Autowired
private OrderService orderService; /**
* 标识===过滤器所属限制类型
* @return int
*/
@Override
protected int getThisRestrictiveType() {
return RiskControlRestrictiveEnum.LimitPhone.getCode();
} /**
* 构造函数---注册到过滤器链
*/
public RiskControlLimitPhoneFilterChain() {
filterChains.add(this);
} /**
* 风控决策引擎执行入口--限制手机号
*
* @param user, 用户ID
* @param manager 风控管理器
* @param restrictive 风控限制
* @author GuoTong
*/
@Override
public boolean execute(User user, RiskControlManager manager, RiskControlRestrictive restrictive) {
boolean restrictiveFlag = false;
try {
restrictiveFlag = super.executeDefaultHandler(user, manager, restrictive,this);
} catch (Exception e) {
log.error("RiskControlLimitAccountFilterChain execute error:", e);
}
return restrictiveFlag;
} @Override
protected int countRiskControlLimit(String startTime, String endTime, User user) {
String mobile = user.getMobile();
if (StringUtils.isBlank(mobile)) {
return 0;
}
return orderService.countRiskControlPhoneLimit(startTime, endTime, mobile);
} /**
* 保存用户--进入限制桶
* 子类必须重写
* @param riskControlUsers riskControlUsers
*/
protected void saveLimitUser(RiskControlUsers riskControlUsers) {
riskControlUsersService.save(riskControlUsers);
} @Override
protected ReleaseTimeSetting getReleaseTimeSetting() {
return riskControlUsersService.selectReleaseTimeData();
} }

SpringBoot+使用过滤器链执行风控决策的更多相关文章

  1. Go Revel - Filters(过滤器链)

    `Fitlers`过滤器链是一个中间件,它们具有单独的功能,并作为管道对请求做链式处理.过滤器链执行框架的所有功能. 对过滤器链的源码分析,请移步 Go Revel - Filter(过滤器)源码分析 ...

  2. SpringBoot自定义过滤器的两种方式及过滤器执行顺序

    第一种 @WebFilter + @ServletComponentScan 注解 1.首先自定义过滤器 如下自定义过滤器 ReqResFilter 必须实现  javax.servlet.Filte ...

  3. Spring Security(2):过滤器链(filter chain)的介绍

    上一节中,主要讲了Spring Security认证和授权的核心组件及核心方法.但是,什么时候调用这些方法呢?答案就是Filter和AOP.Spring Security在我们进行用户认证以及授予权限 ...

  4. 【springboot】过滤器、监听器、拦截器,Aspect切片

    转自: https://blog.csdn.net/cp026la/article/details/86501019 简介: 本章介绍拦截器.过滤器.切片对请求拦截的使用与区别,以及监听器在 spri ...

  5. SpringBoot学习(八)-->SpringBoot之过滤器、监听器

    本文将直接使用@WebFilter和@WebListener的方式,完成一个Filter 和一个 Listener. 过滤器(Filter)和 监听器(Listener)的注册方法和 Servlet ...

  6. springboot 增加过滤器方法

    在访问服务器时,我们需要控制用户是否允许权限,这个时候可以使用过滤器. 在springboot 配置过滤器的方法如下: 编写过滤器代码: package com.neo.filter; import ...

  7. spring boot 自定义过滤器链

    spring boot 会按照order值的大小,从大到小的顺序来依次过滤. 贴下代码: package com.osp.ucenter; import org.springframework.boo ...

  8. 过滤器链chain.doFilter(request,response)含义

    过滤器的生命周期一般都要经过下面三个阶段: 初始化 当容器第一次加载该过滤器时,init() 方法将被调用.该类在这个方法中包含了一个指向 Filter Config 对象的引用. 过滤 过滤器的大多 ...

  9. springboot jsp,过滤器,拦截器

    springboot使用jsp,过滤器,拦截器(拦截器与过滤器区别重点) jsp使用配置 一 创建springboot项目在maven中暂时只添加两个Dependencies :devtools(热部 ...

  10. SpringBoot图文教程6—SpringBoot中过滤器的使用

    有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文系列教程技术大纲 鹿老师的Java笔记 SpringBo ...

随机推荐

  1. uniapp同城社区交友 仿小红书 APP小程序源码 含后台管理和网页端

    注意(预防被骗) 本程序仅在 破晓店铺(https://shop.abyssdawn.com/).破晓一代网络科技淘宝店 出售其余地方均为骗子. 关于本程序 本程序适用于各种同城社区交友类产品,例如同 ...

  2. Failed to run MSBuild command 错误问题解决

    场景:提示:这里简述项目相关背景: CMake 报错 CMake ERROR Failed to run MSBuild command: MSBuild.exe.如下图所示: 问题描述提示:这里描述 ...

  3. [转]C#从MySQL数据库中读取

    实现了数据库的建表.存储数据的功能后,还需要实现数据库的读取,综合查资料后发现有两种发发比较好; 一.如需要界面操作,需要将数据表格在界面上显示出来的话,需要使用DataGrid控件. 基本操作流程: ...

  4. IM开发干货分享:IM客户端不同版本兼容运行的技术思路和实践总结

    本文由巩鹏军分享,原题"IM兼容性基建",本文有修订. 1.引言 一个成熟的IM成品,在运营过程中随着时间的推移,会发布不同的版本,但为了用户体验并不能强制要求用户必须升级到最新版 ...

  5. 阿里IM技术分享(七):闲鱼IM的在线、离线聊天数据同步机制优化实践

    本文由阿里闲鱼技术团队书闲分享,原题"如何有效缩短闲鱼消息处理时长",有修订和改动,感谢作者的分享. 1.引言 闲鱼技术团队围绕IM这个技术范畴,已经分享了好几篇实践性总结文章,本 ...

  6. 【狂神说Java】Java零基础学习笔记-面向对象

    [狂神说Java]Java零基础学习笔记-面向对象 面向对象01:什么是面向对象 面向过程&面向对象 面向过程思想 步骤清晰简单,第一步做什么,第二步做什么.... 面对过程适合处理一些较为简 ...

  7. Redis常用指令(详细)

    # Redis 常用指令## 基础命令### 启动与连接```bash# 启动 Redis 服务redis-server# 连接 Redis 客户端redis-cli```### 基本操作```bas ...

  8. superset 1.3版本WIN10安装实录

    首先说下,为什么要这么做,因为二开需要,二开要有源码,然后对源码修改,编译,所以不能通过类似https://zhuanlan.zhihu.com/p/271695878这种方式,直接安装: 1.去Gi ...

  9. python包学习:-了解

    本节先做一些了解. numpy 参考:NumPy使用 NumPy 教程 NumPy是Python中科学计算的基础包.它是一个Python库,提供多维数组对象,各种派生对象(如掩码数组和矩阵),以及用于 ...

  10. Nmap 图形界面使用

    Nmap 图形界面的使用 Zenmap,作为Nmap的图形用户界面(GUI),为用户提供了一个直观.易用的方式来执行网络扫描和分析.以下是一个关于如何使用Zenmap的详细指南. 扫描主机 使用Zen ...