跳到主要内容

FreeKit.Auth.Host OpenIddict 测试说明

本文档对应迁移后的独立认证服务 FreeKit.Auth.Host,用于验证 OpenIddict bootstrap、登录页、授权码流和 userinfo

1. 当前实现边界

  • 认证服务项目:src/Services/Auth/FreeKit.Auth.Host
  • OpenIddict 端点:/connect/authorize/connect/token/connect/userinfo
  • 当前端点走根路径,不再使用旧的 /identity_api/connect/*
  • 服务启动时会自动完成两类初始化:
    • OpenIddict 表初始化
    • identity_connect_claim_mapping 表和默认 claim 映射初始化
  • 默认 bootstrap 客户端:freekit.consolefreekit.cmskitfreekit.im

2. 推荐本地测试方式

优先使用 Development 环境做 smoke test。

当前仓库里的本地 Development 配置:

  • 服务地址:https://localhost:7005
  • 数据库:localhost:3308 / freekit
  • 配置文件:src/Services/Auth/FreeKit.Auth.Host/appsettings.Development.json

不建议默认使用 https-local-prod 做本地 smoke test,因为 LocalProduction 可能指向外部 MySQL。

启动命令

dotnet run --project src/Services/Auth/FreeKit.Auth.Host/FreeKit.Auth.Host.csproj --launch-profile https-dev

启动成功后,浏览器直接打开:

https://localhost:7005/connect/login

如果登录页能正常打开,说明基础路由已经对上。

3. 启动后数据库自检

3.1 Scope 校验

SELECT name, display_name, resources
FROM open_iddict_scope
WHERE name IN ('openid', 'profile', 'email', 'roles', 'console', 'cmskit', 'im')
ORDER BY name;

预期至少能看到:

  • openid
  • profile
  • email
  • roles
  • console

3.2 Client 校验

SELECT client_id, display_name, redirect_uris, permissions, requirements
FROM open_iddict_application
WHERE client_id IN ('freekit.console', 'freekit.cmskit', 'freekit.im')
ORDER BY client_id;

本地最小 smoke test 重点看 freekit.console

  • client_id = freekit.console
  • redirect_uris 包含 https://localhost:7005/connect/test-callback
  • 开启 PKCE

3.3 Claim 映射校验

SELECT claim_type, user_property_name, source_type, is_enabled, sort_code
FROM identity_connect_claim_mapping
ORDER BY sort_code;

预期至少能看到:

  • sub -> Id
  • name -> UserName
  • email -> Email
  • role -> UserRole

如果这个表不存在或为空,重启 FreeKit.Auth.Host 后会自动补齐。

4. 最小浏览器 Smoke Test

本地最简单的验证方式,是直接使用内置的 freekit.console 客户端和测试回调页。

固定 PKCE 参数

  • code_verifier: dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
  • code_challenge: E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM

authorize 地址

https://localhost:7005/connect/authorize?client_id=freekit.console&response_type=code&scope=openid%20profile%20email%20roles%20console&redirect_uri=https://localhost:7005/connect/test-callback&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256&state=devflow

预期流程

  1. 未登录时跳到 https://localhost:7005/connect/login
  2. 使用本地数据库里一个可登录账号完成登录
  3. 成功后会跳到 https://localhost:7005/connect/test-callback
  4. 页面展示回调参数(code、state 等),并提供「用 Code 换 Token」按钮
  5. 点击按钮后,页面自动调用 /connect/token 兑换 Token 并展示结果
  6. 可继续点击「UserInfo」按钮验证 token 有效性

/connect/test-callback 是内置的回调测试页面,由 ConnectController.TestCallback() 提供,用于本地 smoke test。前端 SPA 应使用自己的回调地址(如 {CmsKitClient}/auth/callback)。

5. Token 交换测试

把上一步拿到的 code 替换到下面命令里。

如果你想直接跑一键 smoke test,仓库里已经有脚本:

pwsh ./build/smoke_test_auth_openiddict.ps1 -UserName "你的账号" -Password "你的密码"

脚本会自动完成:

  • authorize
  • 登录提交
  • callback 取 code
  • /connect/token 兑换 token

默认目标地址是 https://localhost:7005,默认客户端是 freekit.console

curl 示例

curl.exe -k --request POST "https://localhost:7005/connect/token" \
--header "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=authorization_code" \
--data-urlencode "client_id=freekit.console" \
--data-urlencode "code=把这里替换成回调里的code" \
--data-urlencode "redirect_uri=https://localhost:7005/connect/test-callback" \
--data-urlencode "code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"

预期返回

{
"token_type": "Bearer",
"access_token": "...",
"expires_in": 3600,
"refresh_token": "..."
}

6. userinfo 测试

access_token 替换进去。

curl.exe -k --request GET "https://localhost:7005/connect/userinfo" \
--header "Authorization: Bearer 把这里替换成access_token"

预期返回用户 claims,例如:

{
"sub": "用户ID",
"name": "用户名",
"email": "邮箱",
"role": [
"Admin"
]
}

7. 如果你要联调前端客户端

除了内置 freekit.console,当前还预置了两个前端客户端:

  • freekit.cmskit
  • freekit.im

它们的回调地址来自:

  • Host.CmsKitClient

对应默认配置在:src/Services/Auth/FreeKit.Auth.Host/appsettings.json

如果你本地也启动了前端,可以把 authorize 里的参数切到对应 client:

  • client_id=freekit.cmskit
  • scope=openid profile email roles cmskit
  • redirect_uri={CmsKitClient}/auth/callback

但在纯后端 smoke test 阶段,优先建议先用 freekit.console

8. 常见问题优先排查

8.1 /identity_api/connect/... 返回 request not found

这是旧路径。迁移后的 FreeKit.Auth.Host 要使用根路径:

  • 正确:/connect/authorize
  • 错误:/identity_api/connect/authorize

8.2 登录成功后拿不到 code

优先检查:

  • redirect_uri 是否和应用表里的配置完全一致
  • client_id 是否真的存在于 open_iddict_application
  • code_challenge / code_verifier 是否配对
  • 登录使用的账号是否真能登录,是否被锁定

8.3 /connect/token 返回 invalid_grant

优先检查:

  • code 是否刚生成,是否已被消费过
  • redirect_uri 是否与 authorize 阶段完全一致
  • code_verifier 是否与 authorize 阶段匹配

8.4 本地突然连到了外部数据库

检查启动 profile。

本地 smoke test 建议固定使用:

  • https-dev

不要默认使用:

  • https-local-prod

8.5 claim 丢失或 userinfo 字段不全

先查:

SELECT claim_type, user_property_name, source_type, is_enabled, sort_code
FROM identity_connect_claim_mapping
ORDER BY sort_code;

如果表为空,重启服务后会自动回填默认映射。

9. 最小通过标准

满足下面四条,就可以认为迁移后的 OpenIddict 已基本可用:

  1. https://localhost:7005/connect/login 能正常打开
  2. open_iddict_scopeopen_iddict_applicationidentity_connect_claim_mapping 已自动初始化
  3. 浏览器访问 authorize 后能在 test-callback 页面拿到 code
  4. /connect/token 能成功换出 access_token