访问策略
访问策略按请求的 IP、地区、时段、User-Agent、路径、用户、角色、客户端类型、接口权限码等属性放行、拒绝或只记录请求,管的是「从哪里、什么时候、以什么方式访问」。它与权限条件分工不同:
| 访问策略 | 权限条件 | |
|---|---|---|
| 挂在哪里 | 独立的策略,不看授权 | 某一条角色授权或用户直授 |
| 作用 | 整个请求放行或拒绝 | 只收窄这一条授权 |
| 平台超管、租户所有者 | 同样受约束 | 不受约束(不走授权行) |
| 求值时机 | 认证前、认证后、登录时 | 鉴权时 |
两者共用同一套条件属性与运算符,命中都记进「条件命中」。登录失败过多的 IP 自动封禁也在这里管理。
策略的组成
| 字段 | 说明 |
|---|---|
| 策略编码 | 同一层内唯一,不能有空白 |
| 动作 | 只记录:命中只写命中记录;拒绝:命中即拒绝;放行:同一层里压过拒绝,用来给拒绝策略开例外 |
| 条件 | 同一条件组内全部满足这组才满足,任一组满足策略就命中;至少一条条件,空条件会匹配所有请求,不允许保存 |
| 优先级 | 越小越先求;同时命中多条时只决定报告哪一条,不改变放行压过拒绝的结论 |
| 状态与生效期 | 启用且当前时间落在生效时间~失效时间内才求值 |
条件属性见权限模型 · 权限条件的属性表,访问策略能用其中除数据行属性(resource.<字段>)以外的全部属性。environment.ip 的条件值可写单个地址或 CIDR 列表,时间类属性按 Saas:Conditions:TimeZone 计算,取不到值的条件按不满足处理。
两层与裁决
- 平台级:在平台上下文维护,对全部请求生效。
- 租户级:租户管理员在自己的租户里维护,只作用于该租户已登录的请求和登录进该租户的那一次;匿名请求不按请求头里的租户选策略。租户看不到平台的策略。
- 同一层里放行压过拒绝;平台的拒绝,租户的放行救不回来。
- 认证前已经拦下的平台拒绝,认证后的平台放行救不回来(请求已经结束)。要给认证前的拒绝开例外,放行策略也只能用认证前就能判定的条件。
求值时机
时机由策略引用的属性自动决定,列表的「求值时机」列显示它:
| 时机 | 哪些策略 | 位置 | 被拒绝时 |
|---|---|---|---|
| 认证前 | 平台级、只引用 environment.ip、environment.geo.*、environment.location、时间类属性、environment.client.userAgent、resource.path、resource.method 的策略 | 请求管线最前,接口、实时通道、/uploads 静态文件与接口文档都在它后面 | 403「访问被安全策略拒绝。」 |
| 认证后 | 平台级里用到用户、角色、部门、客户端类型、端点权限码等属性的策略,加上已登录请求所在租户的全部策略 | 认证、租户解析与路由之后,会话闸门与授权之前;匿名接口、Minimal API 与实时通道的协商请求同样经过 | 403「访问被安全策略拒绝。」 |
| 登录时 | 与认证后同样的两层,按登录的用户与目标租户求 | 核对凭据之后、签发令牌之前;覆盖密码、两步验证、邮箱、手机号、第三方登录与切换租户 | 登录失败「当前网络或时段不允许登录。」,登录日志结果为「访问策略拒绝」 |
OAuth 授权码换令牌与模仿登录不做登录时检查:前者由第三方服务端发起,后者发起人自己的请求已经过了闸门。策略求值本身出错时记错误日志、本次放行。各时机在管线中的位置见请求生命周期。
从模板新建
「系统管理 → 访问策略」的「从模板新建」列出六条预置模板,平台与租户都能用;平台初始化时按模板写好同名的预置策略:
| 模板 | 用途 | 平台预置策略 |
|---|---|---|
| IP 黑名单 | 命中的地址或网段拒绝一切请求 | 拒绝,停用 |
| 管理员只能在办公网访问 | 超级管理员与租户所有者只能从办公网访问 | 拒绝,停用 |
| 敏感操作限定网络 | 导出、删除、模仿登录与授权类操作只能从办公网发起 | 拒绝,停用 |
| 非工作时间访问 | 周末全天,以及工作日 08:00–20:00 之外的访问 | 只记录,启用 |
| 境外访问 | 离线地址库查得到国家、且国家不是中国的访问 | 只记录,启用 |
| 爬虫与脚本访问 | 没有 User-Agent 或是常见脚本工具的请求,开放接口签名调用除外 | 只记录,启用 |
模板里的办公网段与黑名单地址是文档保留网段(203.0.113.0/24、2001:db8::/32),只作占位,启用前换成真实网段。离线地址库里港澳台的国家是「中国」,要算作境外须另加省份条件。
启用拦截
- 新建一律只记录,从模板新建也一样。先看命中记录,或试运行确认无误,再在列表里「启用拦截」「设为放行」或「改为只记录」。
- 不会把自己锁在外面:保存后是启用中的拒绝策略时(启用拦截、启用、编辑),先拿当前这个请求试一次,会拦下自己就不保存。它只试当前请求:按路径、方法拒绝的策略可能不拦保存请求、却拦别的页面,这种情况见部署 · 误封了自己。
- 试运行:对已保存的策略或编辑中的条件草稿,按填写的 IP、时刻、User-Agent、路径、方法、用户与端点权限码求一次,给出会不会拦下、各条件取到的值。只求这一条,不看生效期与其他策略;不填的项取当前请求与当前用户;草稿按「拒绝」来试;不模拟客户端类型(模拟请求按匿名算)。
命中记录
「审计中心 → 条件命中」收访问策略与权限条件两种来源的命中,访问策略列表的「命中记录」直接跳过去只看那一条,列表也显示每条策略近 24 小时的命中次数。
- 只记录、拒绝、放行的命中都记;拒绝被同一层的放行豁免时记为「未拦截」。权限条件在
LogOnly模式下本该拒绝的请求也记在这里。 - 平台策略的命中记在平台,租户策略与权限条件的命中记在该租户。
- 同一策略、动作、时机、是否拦截、IP、方法、路径、用户在同一分钟里合并为一行、累计次数;内存里的合并键上限见
Saas:AccessPolicy:HitBufferCapacity。 - 按月分表,保留期跟其他日志一样读
saas.log.retention-days;按 TraceId、IP、用户可在日志链路追踪里与其他日志串起来看。暂不提供导出。
登录失败自动封禁
同一 IP 在计数窗口内登录失败(跨账号累计)达到上限即被暂时封禁,封禁期间这个 IP 的全部请求返回 429「登录失败次数过多,当前 IP 已被暂时封禁。」并带 Retry-After。
- 参数
saas.security.login-auto-ban,缺省关闭;打开后缺省 10 分钟内失败 20 次封 30 分钟,24 小时内再犯时长翻倍,最长 1440 分钟。只认平台这一条,租户不能覆盖。 - 计入的是账号密码不对、登录验证码不对、两步验证码不对这类失败;被访问策略拒绝的登录不计,认证前命中平台放行策略的 IP 不计。
- 平台上下文的访问策略页有「自动封禁」:查看当前封禁、解封(权限码
saas:access-policy:ban,解封同时清零计数),有参数配置编辑权限时直接在这里改参数。 - 多实例部署必须启用 Redis,计数与名单才在节点间共享,见部署 · 访问策略与真实 IP。
权限码与菜单
| 权限码 | 说明 |
|---|---|
saas:access-policy:read | 查看访问策略与当前封禁(菜单「系统管理 → 访问策略」) |
saas:access-policy:create | 新建(只能建成只记录) |
saas:access-policy:update | 修改条件、优先级、生效期与动作(含启用拦截) |
saas:access-policy:status | 启用、停用 |
saas:access-policy:delete | 删除,历史命中记录保留 |
saas:access-policy:trial | 试运行 |
saas:access-policy:ban | 解除自动封禁,只在平台生效 |
saas:access-policy-hit:read | 查看命中记录(菜单「审计中心 → 条件命中」) |
平台与租户两侧都有这些权限码(ban 只在平台)。初始化的专业版、企业版套餐都含除 ban 外的全部;已有套餐不会自动带上,要到「租户管理 → 版本套餐」勾选。
运行与运维
- 真实客户端 IP、出错时放行、多实例生效时延、误封自己后的解围,见部署 · 访问策略与真实 IP。
- 总开关与刷新间隔见配置 ·
Saas:AccessPolicy。 - 策略与条件存在平台库,命中记录随其他日志存在各租户的库里,见多租户 · 库隔离。
