更好的门户默认 Auth
默认 Auth 拥有账户目录; BP 继续拥有应用程序权限和角色定义. 用户身份、团体和资格被限定为租户,默认为应用程序。 访问令牌和刷新会话总是应用的. 没有在应用程序中共享 BP 会话 .
需要节点.js 24. 现有的WorkOS和Authress登录,刷新,角色同步和用户管理行为不变. 他们唯一的整合变化是共享确认-连接发行车钩.
部署模式
| 设置 | 简单( 默认) | 高级 |
|---|---|---|
mode | simple,包括省略时 | advanced,明确配置 |
| 存储 | 原子弹JSON,一个作家 | PostgreSQL、交易记录和租户锁 |
| 每例租户 | 一,用BP房客锁 | 多个已启用租户 |
| 账户 | 总计10个,包括已停用/未核实/未安装账户 | 无应用程序账户上限 |
| 复制品 | 一个 | 多个, 共享安装配置和签名/ 加密密钥 |
插件配置保留 issuer, (中文(简体) ), audience, (中文(简体) ), accessTokenSeconds (900个), refreshTokenSeconds (604,000) (中文(简体) ), keyStorePath 财务报告和审定财务报表 userStorePath高级添加 postgresUrl 和要求 encryptionKey:一个基数64-编码为32字节的键. 使用您部署的秘密配置来提供秘密,并在每个复制品上使用相同的发行者,受众,密钥和PostgreSQL数据库. 启动 Advance 之前提供 RSA 密钥文件; 绝不让单个复制人独立生成签名身份 .
简单创建单独的 <userStorePath>.crypto.json 键文件,只有所有者权限。 用身份商店备份这个文件并签名钥匙. 高级在迁移已有的加密因子或队列邮件时使用精确的加密密钥. JWT签名密钥和因子/邮件加密密钥的目的不同.
JSON锁拒绝同时编剧. 在同一主机上显示已死进程可以自动恢复;模糊的所有权,另一个主机,或中断的锁定恢复操作要求操作者在删除所显示的程序之前先核实前一个进程已停止 .lock 编号 : .lock.recover 文档。 优雅的服务处置排出存储并放出其锁.
单向移徙
- 停止简单实例并备份身份,签名,加密和BP靴子状态.
- 设定
mode: advanced, (中文(简体) ),postgresUrl共享资源encryptionKey。保留原件userStorePath为这个启动. - 开始一个移民案例。 它在数据库工作前写出高级意向,在交易中导入,验证所导入的每一个记录,在PostgreSQL中记录出源检查和,标记完成并去除活性的JSON身份文件.
- 用相同的安装配置和密钥启动所剩的复制品. 保护每个复制品的持久状态位置.
<userStorePath>.mode.json 和 PostgreSQL 迁移分类账保存完好。 简单的启动拒绝标记即使 mode 或 JSON 文件缺失。 数据库的断绝从未打开JSON倒置. 重新使用相同的剩余来源完成清理; 不同的来源无法关闭操作员调查 。 限制许可 .v1.backup 财务报告和审定财务报表 .advanced.backup 文档是有意的回收副本:根据备份政策保留/删除。 签名密钥,加密密钥和BP靴子/配置状态永远不会被迁移去除.
遗产账户保存ID,bcrypt散列和现有的应用角色任务. 它们的目录仍然有租户范围并锁定,现有的应用任务——包括空任务——被标记为初始化。 后遗症bcrypt比较保留了它最初的72字节的截取行为,包括更长的UTF-8口令. 成功登录使用完整提交的密码将密码升级至1024字节至Argon2id;较长的遗留密码保留了bcrypt,直到在当前限制范围内更改为密码. 导入时刷新会话无效; 用户再次签名 。 一个超过10个用户的Simple商店保留了登录/恢复,但无法创建账户;一个在多个租户拥有账户的商店需要Advance.
遗产标识符相撞从不合并账户或根据文件顺序选择所有者. 拼接用户名保留准确的,对大小写敏感的密码签名;模棱两可的常态标识符保留下来,不能用于电子邮件查询或新注册. 冲突邮件被保存为 legacyEmail 迁移元数据并删除正在运行的电子邮件字段。 这些账户可以签入其原始用户名和密码,但须符合外交部的要求,然后在账户中添加并验证一个独特的电子邮件。 原店仍保存在迁移备份中.
所有已迁移的遗留账户都保留密码登录,但须接受启用账户检查和外交部的政策,即使邮件发送没有配置。 这种仅限迁移的例外也适用于保留电子邮件的账户;迁移从未在地址被核实时标明. 没有活动电子邮件的账户可以从账户中添加并校验一个 。 新的自助登记仍然需要经过核实的电子邮件.
租户和应用程序配置
设定 userIsolation 租户范围:
app:每个应用程序都有单独的用户,标识符,组和证书. 这是新房客的默认.tenant:应用共享租户账户目录. 角色任务、外部重定向、会话和信使仍然是针对应用的.
这种设置一直存在,并被第一个账户的创建所锁住,包括靴子、邀请接受和社会供给。 配置 API 拒绝后续的更改; 身份交易也执行边界 。 共享租户目录不会将用户登录到另一个应用程序.
租户共同账户,只设定租户 directoryAdminAppId 给那个租户信任的行政应用程序 只有其授权的管理员(和现有的管理app)才能禁用共享账户,取消所有会话,或修改组成员. 其他应用程序管理员可以指定角色,邀请账户,并绘制现有组图,以图取自自己的应用程序角色. 他们不能通过应用程序配置授予自己目录权限 。 账户列表使用光标 pagination,角色编辑将直接任务与组产生的权限分开.
应用程序设置 :
| 设置 | 行为 |
|---|---|
registration | invite-only 默认; public 财务报告和审定财务报表 closed 支持 |
defaultRoleIds | JSON 阵列, 默认 []; 现有的应用角色 ID 只, 从未 * |
requireMfa | 登录时需要因数注册/核查 |
mailTransport | postal 或者说 http |
mailUrl, (中文(简体) ), mailFrom | 发送端点/基准 URL和发送者 |
mailApiKey | 保护邮政服务器 API 密钥 |
mailHeaders | 为自定义的 HTTP 服务保护 JSON 信头对象 |
socialConnections | 保护 JSON 系列连接对象如下: |
默认角色在第一次完成登录时,在经过需要的校验/因素后使用一次. 空的初始化也持续存在。 行政/邀请任务优先。 更改默认或撤销角色不会在后期登录时重新授予它们. Group成员只贡献了当前app的角色映射. 现有 * root含义不变;普通用户没有角色,除非被指定.
挂载账户路径
与现有 /login, (中文(简体) ), /logout, (中文(简体) ), /register 财务报告和审定财务报表 /refresh,在每一个应用中挂载这些路径:
/account(单位:千美元)account.index:注册、电子邮件核查/转发、密码重置、配置/密码/电子邮件更改、因子录入/删除、恢复码显示和活动会话取消./social(单位:千美元)social.index:社会上签名和明确的账户链接;其app-shell URL是提供者的注册回调./users(单位:千美元)users.index:账户启用/失效,邀请,应用角色,组,交付失败和审计事件. 授予预定管理员读取/更新权限。 变异需要外交部的高度.
Bootstrap 渲染器在 BP 外壳中运行,并使用其共享的 Auth 运行时间. 电子邮件链接将他们的一用证明保存在URL碎片中,只提交到POST正文中,使其远离访问-log URL. 他们使用挂载的app- shell 账户 URL; 允许公共注册或邀请用户而不挂载失败, 而不是发送无法使用的链接 .
/register 继续部署靴子,仅限于配置的管理租户/应用程序和部署设置标志。 高级要求同样明确 setupToken 在每个复制件上; 简单可以生成只所有者 <userStorePath>.setup.json 文档。 客户注册不会关闭管理拖网;它自己的持久完成标记会阻止第二个管理员拖网。 靴子管理器在接收可用的会话前必须注册 TOTP 或密码 。 此端点不能授予任意应用程序中的root, 行政用户 API 也不能修改靴子陷阱身份 .
已创建/重置的密码现在使用Argon2id,最少有12个字符,最多有1024个UTF-8字节,有常见的密码拒绝. 密码恢复需要电子邮件验证,并保存注册因素. TOTP使用回放保护;密码需要用户验证并验证RP,来源,质疑和证书所有权. Entrollment生产出十个一用回收代码,一次显示并存储散列. 在删除最后一个因素之前, 输入替换 .
对于租户共享的账户,密码只在注册主机名上工作. 保留一个认证或恢复代码,供其他应用程序主机名使用. 如果两者都不可用,请在密码的原始应用程序上签名,并在重新测试另一个应用程序之前在账户中添加一个认证器. 登录和高程返回恢复指令,而不是空洞的挑战;它们从未绕过现有的外交部,也从未仅使用密码授权替换注册.
过期和被撤销的会话在会话发布和账号页读取期间会在其应用中被浏览. 账户页面只查询已签名的用户活动会话,并显示每页100个.
登录节流既适用账户预算,也适用100个尝试/10分钟客户端处理预算。 在反向代理服务器后方配置 betterportal.trustedProxyIps 并启用 trustedProxyHeaders 页:1 X-Forwarded-For (或 cfProxy 给云旗的 CF-Connecting-IP) (中文(简体) ). 代理必须覆盖或附加实际连接客户端地址. 转发的链条从套接字对等端向第一个不可信地址穿行;跳出后被骗的地址被忽略. 不信任的同龄人,缺少信头和错误的链条会倒回套接字地址. 在未配置代理信任的情况下, 客户端会共享套接字地址预算 .
刷新符牌在每个刷新符上旋转. 重放会撤销其家族; 登录、 账户禁用、 密码更改和因数更改会撤销适用的会话 。 浏览器刷新器使用Web Locks API来协调可用的标签. 其他服务机构已经发放的进入令牌仍受正常失效的限制;不承诺立即发放进入令牌.
电子邮件发送
邮政发送 JSON 给 <mailUrl>/api/v1/send/message,与 X-Server-API-Key 邮政 to, (中文(简体) ), from, (中文(简体) ), subject, (中文(简体) ), plain_body, (中文(简体) ), html_body 字段。 HTTP 和 JSON 都成功 status: "success" 需要这样做。 见 邮局派API来。 。 。 .
设定 mailUrl 地址和地址 mailApiKey 到服务器 API 从 Postal 的证书页面。 在排队前拒绝一个缺失的密钥; 发送重验证围绕白空间的密钥和修饰 。 自定义信头不能覆盖此密钥 。 邮政可以返回 HTTP 200 与 AccessDenied: 这意味着提供者拒绝证书,登录为 provider_access_denied。纠正 Postal 服务器的密钥,然后在 /users 或通过账户回收重新发送核查。 在修改配置时, 自动重试仍然可用 。 登录拒绝诊断区分未经验证的电子邮件(auth.login.email_unverified),无效的证书和没有日志账户标识符或密码的拖动.
对于一个使用未验证的电子邮件的用户,经授权的管理员可以在 /users 并复制或打开,而不发送邮件。 这使用相同的单用30分钟账户核查流程,需要现有用户管理许可和多功能飞行器提升。 共享租户账户需要指定目录管理应用. 链接生成被审计;该秘密仅由管理POST返回,不存储在审计记录中,被排除在普通用户列表之外. 挂载应用程序中的账户页面以启用此流量 .
自定义 HTTP 发送 POST {from,to,subject,text,html} 改为 mailUrl 使用已配置的服务器侧头;任何 2xx 响应都成功。 需要使用HTTPS,但本地主机除外。 改编内容被否决. 没有SMTP运输工具.
邮件工作以相应的身份/挑战突变并加密其敏感有效载荷。 租来的工人用回扣5次 PostgreSQL使用部分指数选择最多100个到期的待决/过期租赁工作,不包括交付历史. 发送在解密或发送队列中的信件之前重新验证当前配置的 URL 。 简单将未完成/失败的工作限制为每个应用程序500个,并保留最新的100个成功交付记录. /users 通过部分索引查询无法执行,并显示每页100个光标导航和重试,而不披露密钥或重设链接。 供应商答复机构和全权证书没有记录。 交付是至少一次:在交付后发生崩溃,但在确认前可以重新发送相同的一用链接.
社会联系
每个条目包含 id, (中文(简体) ), kind (单位:千美元)google, (中文(简体) ), microsoft, (中文(简体) ), github, (中文(简体) ), clientId, (中文(简体) ), clientSecret,并且——对于微软来说——一个明确的目录 tenantId。注册每个应用程序 /social 与其提供者一起的 shell URL 。 微软个人账户可以使用其专用消费目录;无限制 common/多种发件人的发现是故意不启用的.
Google/Microsoft使用OIDC代码流;GitHub使用其OAuth代码和配置/电子邮件API. 全部使用S256 PKCE和短寿命的一用服务器状态,绑定在浏览器持有的秘密和启动的app/起源上. OIDC通过非ce、发行商和观众额外验证 openid-client。在身份查询后,提供者访问令牌将被丢弃.
新的社会供应需要公共登记和经核实的提供者电子邮件。 现有的匹配邮件永远不会自动链接:先签名,然后从账户中明确链接提供者。 无法证明经核实的电子邮件的供应商(包括一些微软租户)首先需要电子邮件登记/核查。 链接身份使用发件人+稳定主题,独立于随后的电子邮件更改.
链接批准被绑定在启动的应用会话上,并活过提供者重定向和普通刷新;另一个或被撤销的会话无法完成. 脱钩需要高地和经核实的本地密码作为剩余的登录方法. 提供者解除链接可取消现有的会话.
高级认证
连同现有的路线授权声明如下:
export const auth = {
required: true,
permissions: [], // Supply this action's actual permissions.
elevation: { minimum: "mfa" as const, maxAgeSeconds: 300 }
};
使用 minimum: "confirm" 仅用于确认的动作。 存在 elevation 即使 required 被省略/伪造。 先检查权限; root 不绕过高地 。 关于依赖资源的决定,请打电话 ctx.requireElevation({minimum: "mfa"}) 在资源授权和任何副作用之前。 溪流航道应在溪流开始前在航道上宣布海拔.
保证不足返回 HTTP 401 与 RFC 9470's insufficient_user_authentication, (中文(简体) ), WWW-Authenticate范围 BP-Auth-Challenge 头曰. 足够高的地标直接交给处理者,而无需再提出质疑.
运行时间询问配置的 App auth 服务于 /.well-known/bp/auth/elevate,显示其确认/要素流,然后完全重复一次所捕获的请求。 它保留了提交的方法/机构/标题并拒绝陈旧的页面/会议结果。 取消不会注销 。 背景负载不打开对话框,文件上传需要明确的校验/再提交. 在返回挑战前不要执行效果;在经过再测试的突变后,网络失败永远不会再次被自动再测试.
签名的索赔是: elevation: {assurance: "confirmed" | "mfa", verifiedAt, expiresAt}它涵盖该应用中直到到期的所有符合资格的行动,但需符合每项行动的最低保证、新鲜度和普通权限。 肯定不能满足外交部的要求 Elevation 无法超过访问令牌,只保存在浏览器内存中,并在正常的刷新,登录,重新加载或会话/应用更改中消失. 没有发布提升刷新令牌 .
默认 Auth 验证已注册的因子和当前会话状态 。 WorkOS/Authress只披露通用确认回落;它不能满足外交部的要求,无法重新验证上游状态,也无法延长原始访问符的寿命. 自定义认证提供者选择使用发行钩并可能覆盖 beginAuthElevation 编号 : finishAuthElevation简讯/WhatsApp、SAML、通用企业OIDC、SCIM和外部API赠款仍然是后来的适配方;它们没有作为已执行的供应商进行广告.
通用确认使用目的相分离的签名收条,绑定在源令牌上,主题和app上,最多有5分钟的完成窗口. 复制共享签名密钥可以在重定向或重启后完成. 该窗口内可重复完成,但其最初的保证时间戳和访问到期不能通过重放来续延. 默认 Auth 因素挑战仍然存储和一次性使用.
节点, Python 和.NET 执行在处理器前宣布高地并提供有条件的帮助. Go/PHP目前仅提供与现有的SDK范围相符合的船舶协议助手:主机必须首先验证JWT的签名,租户/应用装订和权限,并且当无法执行所宣布的要求时必须失败关闭.
核查
运行正常的工作空间建设,加装并测试出闸. 其他检查:
# Use an isolated test database, never production.
BP_AUTH_TEST_POSTGRES=postgres://... node --import tsx services/nodejs/auth-default/tests/postgres.test.ts
python framework/conformance/check_elevation.py
cd framework/go && go test ./...
# From repository root:
php framework/php/tests/elevation.php
dotnet framework/dotnet/Conformance/bin/Debug/net10.0/Conformance.dll --elevation framework/conformance/elevation-cases.json
共享的固定装置涵盖最小的保证,新鲜度,过期,符号类型和根行为. 浏览器测试覆盖了精确的突变回放,取消,只包含内存高地和应用程序特定的证书迁移. 存储测试练习封顶,隔离,默认角色,挑战回滚/回放,TOTP/恢复,遗产迁移和PostgreSQL复制种族.
WebAuthn测试使用Chrimium的虚拟认证器,并验证入学,来源,所有权和回放. 社会身份测试模拟提供者的回应,电子邮件发送测试模拟HTTP运输. 现场提供者的登录、生产交付、部署负荷和回收程序必须与部署的实际配置相核实.