Skip to content
bitzorcas
中EN

Concept

RiskControl 风险控制

从登录历史、并行风险因子、租户策略、挑战执行、独立证据持久化到生产门禁,系统理解 RiskControl。

Last updated

RiskControl 对一次登录环境做可解释评估,输出 None、Captcha、MFA、StepUp 或 Block。它提高自动化攻击与异常登录的成本,但不替代密码校验、账户状态、授权、限流或审计。

1. 模块边界

层主要类型职责
ContractsRiskAssessment、RiskPolicy、IRiskFactor、Captcha 端口稳定模型、窄端口和 AOT JSON 契约
ApplicationRuleBasedRiskEngine、四个因子、策略 Provider、持久化 Pipeline评估、策略解析和事务外留痕
InfrastructureRiskAssessmentStore统一聚合写入与 QueryShape 读模型
IdentityLoginHistoryProvider、LoginFlow、风险驱动 MFA提供登录事实并执行 Challenge
API / WebsiteCaptcha Filter、Website Captcha EndpointHTTP 适配与匿名表单保护

模块没有独立的风控规则编辑 Endpoint,也没有机器学习模型、地理异常或弱密码因子。当前实现是可扩展的确定性规则引擎。

2. 登录主路径

NoneCaptchaMFA / StepUpBlock

Login Command

一次查询登录历史

四因子并行评估

租户 riskcontrol.policy

RiskAssessment

RequiredChallenge

密码与账户校验

两阶段验证码

密码后 MFA

密码前拒绝

业务事务外独立持久化

LoginFlow 在密码验证前评估。Block 可节省 BCrypt 并抵御爆破;Captcha 先返回挑战再二次提交;MFA 与 StepUp 当前都进入现有 MFA 流;None 继续正常认证。

3. 当前四个因子

因子权重命中条件证据
NewIp20IP 非空且不在最近 30 分钟已知 IP原始 IP、已知数量
NewDevice15DeviceInfo / UserAgent 不在已知设备原始指纹、已知数量
HighFrequency40最近 5 分钟失败次数不少于 3失败次数、阈值
OffHours10业务本地时间 00:00–06:00小时、完整业务时间

四者全部命中最高 85 分。因此默认策略的 Block 区间 91–100 仅靠内建因子不可达;需要扩展因子或调整租户阈值。文档不能把 Block 描述成当前默认信号自然可触发的常见路径。

详见 规则引擎与风险因子。

4. 默认策略

分数LevelChallengeLogin 行为
0–30LowNone继续密码校验
31–50MediumCaptcha生成或校验图形验证码
51–75HighMFA密码通过后要求 MFA
76–90CriticalStepUp当前同样映射到 MFA
91–100BlockBlock密码校验前拒绝

租户可以通过 riskcontrol.policy 整体覆盖区间与 Challenge。读取、JSON 解析或业务校验失败时回退默认策略并记录 Warning;取消请求仍向上传播。

详见 租户策略与证据持久化。

5. Captcha 能力与真实接线

模块提供 ImageCode、Slider、PointSelect 和可选 Behavior Provider。自有 Provider 使用五分钟票据、随机 nonce、盐渍 SHA-256 和 Redis GETDEL 防重放。

实际接线并不等于四类都在业务中使用:

  • LoginFlow 与 Website 都调用 ResolveDefault(),因此使用 ImageCode;
  • Behavior 只有配置 Provider 时注册,否则解析 Behavior 会静默回退 ImageCode;
  • Slider 和 PointSelect 已注册,但未发现业务 Endpoint 选择它们;
  • 通用 RequireCaptchaEndpointFilter 没有挂载到任何端点;
  • 该 Filter 只拒绝 Result Failure,错误答案返回 Success(Passed=false) 时仍放行;
  • Login 二次提交没有验证 ChallengeId 是否属于当前 tenant + pseudo-session;Website 有前缀校验。

详见 Captcha Provider 与一次性票据。

6. 评估事实为什么独立提交

Login.Command 实现 IRiskAssessedRequest。引擎把一次成功评估捕获到 Scoped Execution Context;外层 RiskAssessmentPersistencePipelineBehavior 在业务事务提交、失败返回或抛异常之后,用新的 Unit of Work 写入 SysRiskAssessment。

风险评估与业务事务的分离语义
try
{
// 内层包含登录事务;成功、失败 Result 或异常都先完成业务语义。
return await next(message, cancellationToken);
}
finally
{
// 风险事实使用独立非取消事务,避免随登录失败一起回滚。
await PersistPendingAssessmentAsync();
}

记录失败只写 Error Log,不覆盖登录响应或原始异常。这保护可用性,却也意味着安全证据可能丢失;GA 应增加指标、告警与耐久补偿路径。

7. 查询、租户与隐私

GET /api/risk/assessments 需要 risk-control.assessment.view。Handler 从 ICurrentUser.User.TenantId 取租户,Store 又显式加入 TenantId Predicate,并将分页、排序和标量投影下推到当前 ORM。

两个边界需要明确:

  1. 正式租户模拟时 CurrentUser 仍可能是操作人原租户,而 Effective CurrentTenant 已是目标租户,查询可能落到错误租户;
  2. API Item 返回完整 Factors,其中当前含原始 IP、设备指纹和业务时间,没有脱敏投影。

详见 Identity、Website 与查询集成。

8. 失败策略不是一个全局开关

故障点当前策略
风险因子、历史或引擎异常Engine 返回 Failure;Login 记录 Warning 后无挑战放行
风控设置不可读或非法回退默认策略
Login Captcha 生成 / Provider Failure登录失败
Captcha 答案错误Login 与 Website 拒绝;通用 Filter 当前误放行
Redis 未注册NoOp Ticket Store;生成看似成功,后续验证必失败
风险评估事实写入失败回滚独立 UoW、写日志、保留业务结果
风险历史快照损坏查询返回稳定 Failure

安全设计必须逐场景决定可用性与风险,而不是笼统写“风控失败关闭”。

9. 章节地图

目标页面
理解历史快照、并行因子、分数与可达性规则引擎与风险因子
正确生成、绑定和消费四类挑战Captcha Provider
配置租户策略并理解独立持久化策略与持久化
接入 Login、MFA、Website 与查询 API集成边界
建立安全、隐私、故障和生产门禁测试与生产运维

10. 源码审查入口

Terminal window
# 先审查引擎、因子与实际 Login 消费,不能只看 Contracts。
rg -n "RuleBasedRiskEngine|IRiskFactor|RequiredChallenge|AssessAsync" \
src/Platform/RiskControl src/Platform/Identity -g '*.cs'
# 查找 Captcha 的生成、校验与 Endpoint 接线。
rg -n "GenerateAsync|VerifyAsync|RequireCaptchaEndpointFilter|ResolveDefault" \
src/Platform/RiskControl src/Platform/Identity src/Platform/Website src/Hosts -g '*.cs'
# 当前预期 Filter 没有 Endpoint 挂载,并且没有检查 Passed。
rg -n "AddEndpointFilter<RequireCaptchaEndpointFilter>|GetValueOrThrow\\(\\)\\.Passed" \
src/Hosts/BitzOrcas.Api -g '*.cs'

11. GA 最低证据

  • 通用 Filter 修复 Passed 判断并真正挂载到目标 Endpoint;
  • Login、Website、Filter 都验证 Challenge 的 tenant / session / scenario 绑定;
  • 四个自有 Provider、Resolver、Redis 失败和第三方适配器都有真实合同测试;
  • 行为 Provider 不在 URL 传 Secret,并校验 Provider、Scene、Randstr、UserIp 与响应协议;
  • Risk Engine fail-open 有配置化风险接受、指标、告警和高价值场景例外;
  • 评估查询使用 EffectiveTenantId,并对 IP、设备等证据做权限分级与脱敏;
  • 独立持久化失败进入耐久告警或补偿,而不只是一条日志。

下一篇:规则引擎与风险因子 · 返回平台模块目录

100%

滚轮或按钮缩放 · 放大后拖动画面 · 双击切换 100% / 200%