Commit Graph
2 Commits
Author SHA1 Message Date
xcsandClaude Opus 5 5964a80b28 鉴权中间件:HEAD 按 GET 判 —— 不归一等于「只要登录就能跑任何 GET 处理器」
Hono 在 #dispatch 里把 HEAD 改写成 GET 再分发,而 `c.req.method` 读的是请求行上的
原始方法,仍是 'HEAD';路由注册表只装 HTTP_METHODS 那五个,于是 lookup('HEAD', …)
**必然 miss** → 落进 `?? 'any'` 兜底 → 一个 `ends: []` 的人(Keycloak 里还没配角色的
新员工)照样能执行三个端的全部 GET 处理器。不绕过认证(无凭据仍 401),够不到
POST/PUT/DELETE,响应体被框架丢掉 —— 但它绕过**端授权**:响应头照抄过去
(desk 那两处 content-disposition 带着资料文件名),而 GET 处理器不是都没副作用
(`GET /api/reports/:period` 一路走到 report-service 的 store.save)。

改:查表之前先归一方法;**票据那一路的 GET 判断用同一个归一后的 method**,
否则 HEAD 拿不到票据那条路,两条路行为不一致。

测(auth-middleware.test.ts +3):HEAD 到 ops 路由持只有 workbench 的 token → 403
(与 GET 同款)· HEAD 到自己端内的路由 → 200 · HEAD 上的票据与 GET 同款。
反向验证:撤掉归一那一行,前两条当场红(200 / 401),装回即绿。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015kAzS35kMnZNt4YGgJXtfw
2026-08-25 19:41:43 +08:00
xcs 81a185cd61 app:鉴权中间件 —— Bearer / 票据 → Principal → 按路由归属判 401/403(ADR-012)
鉴权链的核心件:查路由归属表拿 access(public 直接放行),取凭据(Authorization:
Bearer;GET 且没带头时认 ?ticket=),Bearer 走 org.authenticate、票据走
org.principalOf,按端判定后把 principal 放进上下文。401(没凭据/凭据坏了,该
重新登录)与 403(端不够/账号停用,重新登录没用)分得清楚,前端靠这个分辨。

http-env.ts 只加不删:account/session 是 ADR-010 旧物,现役 server.ts 与十来个
路由文件还在读,退役是下一个任务的事。这一轮也不接线到 server.ts —— 接上会让
现役 cookie 会话链断掉。

测试文件按简报逐字照用,唯一偏差是 get/post 两个测试辅助函数包了一层
Promise.resolve:本仓 Hono 4.12 的 app.request() 类型签名是
Response | Promise<Response>,直接赋给 Promise<Response> 类型标注过不了
typecheck;包一层不改变行为(await 对两者结果一致)。
2026-08-25 17:14:30 +08:00