Files
iam-login/docs/webauthn.md
T

71 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# WebAuthn 第二因素
WebAuthn 使用 Spring Security 官方过滤器、WebAuthn4J 校验和 JDBC 仓储。
PostgreSQL 保存 user handle、凭据公钥与签名计数等记录,不保存用户密码或认证器私钥。
AD 仍为用户与组权威;凭据按目录 authority + objectGUID 关联,用户名改名不会换主体。
## 登录与注册
1. `/signin` 使用原生表单 POST 验证 AD 密码,建立 `FACTOR_PASSWORD`。
2. `/signin/mfa`:没有凭据时注册 passkey;已有凭据时验证 passkey。
3. 注册只保存凭据,必须再次实际验证,才取得 `FACTOR_WEBAUTHN`。
4. `/signin/complete` 要求两种因素均在 10 分钟内有效;目前仅显示验证结果,尚不接受 Hydra challenge。
首次注册信任近期 AD 密码验证。已有凭据后的新增注册同时要求密码与 WebAuthn 因素;
本轮 UI 只提供首次注册与验证,不提供新增管理、删除或自助恢复入口。遗失所有 passkey
尚无自助登录途径;生产上线前需要另行确定恢复和初始注册政策,不能把数据库清空作为日常恢复方式。
注册和验证均要求认证器 user verification(例如 PIN 或生物识别)。
Spring Security 负责因素合并、会话轮换、退出和 CSRF。应用仅补目录主体与凭据所有权
限制、首次注册并发检查,以及 challenge 的 5 分钟服务端有效期和单次消费。
没有应用自建登录状态机或认证 Filter。上游 options Filter 位于授权 Filter 前,因而
这些检查在 RelyingPartyOperations 扩展点执行,不能仅靠 URL 授权规则。
## 本地数据库
```sh
# 密码从 shell 或外部权限为 0600 的 env 文件提供;不要写入版本库。
docker compose -p iam-login-dev -f compose.dev.yaml up -d
```
必须设置 `IAM_DEV_DB_PASSWORD`。PostgreSQL 仅发布在 `127.0.0.1:15432`,可用
`IAM_DEV_DB_PORT` 调整端口;数据保存在 Compose named volume 中。
普通 `down` 不删数据,**不要使用 `down -v`**,否则会删除已注册凭据。
应用额外配置:
```yaml
iam:
webauthn:
enabled: true
rp-id: laptop.tail7e769.ts.net
origin: https://laptop.tail7e769.ts.net:18082
spring:
datasource:
url: jdbc:postgresql://127.0.0.1:15432/iam_login
username: iam_login
password: ${IAM_DEV_DB_PASSWORD}
```
同时启用并配置 [AD](ad-login.md)。RP ID 不含协议与端口,origin 必须与浏览器实际
HTTPS 入口完全一致;改变 RP 域名后旧凭据不能直接在新域名使用。
凭据 schema 由 Flyway 管理,采用 Spring Security 7.1.1 官方 PostgreSQL 表结构,
增加主体名称唯一约束和凭据所有者索引。未启用 WebAuthn 时不创建 DataSource,AD-only
路径不需要数据库。数据库不可用时 MFA 失败,不降级为仅密码通过。
## 验证
JVM 回归使用 Testcontainers PostgreSQL 与模拟 AD;不会向真实 AD 提交测试密码。
浏览器用 Chromium 虚拟认证器产生真实注册/断言签名,再交给后端校验:
```sh
scripts/gradle-in-docker test
scripts/gradle-in-docker webauthnBrowserFixture
# 另一终端;测试夹具固定监听 localhost:18083,使用测试证书。
IAM_WEBAUTHN_FIXTURE=1 npm --prefix frontend run test:browser -- webauthn.spec.ts
```
测试专用启动类仅在 test classpath,不进入生产 JAR,也不提供生产调试 API。
真实用户的 passkey 注册、认证器兼容性和 Native 路径仍需独立验收;JVM/虚拟认证器通过
不能代替真实人类或 Native 验收。生产共享 PostgreSQL 的接入留在部署阶段。