Archived
启动自检 issuer 不一致拒绝启动;路由覆盖 fail-closed;Keycloak 配置解析测试(ADR-012)
上一个任务把统一鉴权中心接上了,但缺配置照常起、issuer 配错也照常起 —— 每个请求都 401 还查不出原因。boot() 开头补两道保险:缺 KEYCLOAK_URL/REALM/CLIENT_ID 直接拒绝启动;配了就拉一次 .well-known/openid-configuration 核对 issuer,不一致同样拒绝启动 (话里带期望/实际/KC_HOSTNAME,照后端接入手册第 5 步)。 另加路由覆盖 it 测试:Hono 里每条注册路由都必须能在 appRouteRegistry() 里查到归属,查不到就是一个没人管的权限口子。真库跑通,96 条路由全部 有归属、0 条查不到——把上一个任务里人工核对的结论固化成测试。
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* 启动自检(手册第 5 步;ADR-012):拉 `.well-known/openid-configuration`,
|
||||
* issuer 与本地拼出来的不一致就别起 —— 配错了每个请求都 401 还查不出原因,不如启动时就说清楚。
|
||||
*/
|
||||
import type { KeycloakConfig } from './config.ts';
|
||||
|
||||
export async function checkKeycloakConnection(
|
||||
kc: KeycloakConfig,
|
||||
fetchImpl: typeof fetch = fetch,
|
||||
): Promise<{ issuer: string; clientId: string }> {
|
||||
const url = `${kc.issuer}/.well-known/openid-configuration`;
|
||||
const resp = await fetchImpl(url, { signal: AbortSignal.timeout(5000) });
|
||||
if (!resp.ok) throw new Error(`拉取发现文档失败 (${resp.status}): ${url}`);
|
||||
const conf = (await resp.json()) as { issuer?: unknown };
|
||||
if (conf.issuer !== kc.issuer) {
|
||||
throw new Error(
|
||||
`issuer 不一致!\n 期望: ${kc.issuer}\n 实际: ${String(conf.issuer)}\n` +
|
||||
' → Keycloak 的 KC_HOSTNAME 配错了,或本服务的 KEYCLOAK_URL 写错了',
|
||||
);
|
||||
}
|
||||
return { issuer: kc.issuer, clientId: kc.clientId };
|
||||
}
|
||||
Reference in New Issue
Block a user