跳到主要内容

在 Fulla 上构建应用(OIDC 登录接入)

让您的 Web / 移动 / CLI 应用使用 Fulla 作为身份提供方:标准 OpenID Connect, 任何合规库即插即用,无自定义协议。

1. 注册您的应用​

  • 已启用自助注册的部署:门户 → 我的应用 → 注册应用。选择:
    • PUBLIC:浏览器 / 移动应用(授权码 + PKCE,无密钥);
    • CONFIDENTIAL:服务端应用(客户端密钥,仅显示一次——请存入密钥管理服务)。
  • 其它部署请联系 Fulla 管理员创建客户端。
  • 登记精确的回调 URI(开发环境外必须 https://)。
  • 从自助白名单中选择 scope(默认 openid、profile、email)。

1a. 编程式注册(RFC 7591)​

自动化与 Terraform 式供给可以直接调 POST /oauth2/register 注册客户端。 该端点仅管理员可用:Bearer 令牌须属于持有 admin 角色的用户 (开放注册是刻意的非目标)。管理控制台中的"注册应用(RFC 7591)"表单 调用的就是它。

# 1) 获取管理员 Bearer 令牌。全新开发环境用种子 fulla-portal PUBLIC
# 客户端与引导管理员即可完整走通:
VERIFIER=$(openssl rand -base64 48 | tr '+/' '-_' | tr -d '=')
CHALLENGE=$(printf %s "$VERIFIER" | openssl dgst -sha256 -binary | base64 | tr '+/' '-_' | tr -d '=')
CODE=$(curl -s -X POST 'http://localhost:5555/oauth2/login?json=true' \
-d "username=admin&password=ADMIN_PASSWORD" \
-d "client_id=fulla-portal&redirect_uri=http://localhost:5173/callback" \
-d "scope=openid&state=dcr&code_challenge=$CHALLENGE&code_challenge_method=S256" \
| jq -r .code)
TOKEN=$(curl -s -X POST http://localhost:5555/oauth2/token \
-d "grant_type=authorization_code&code=$CODE" \
-d "client_id=fulla-portal&redirect_uri=http://localhost:5173/callback" \
-d "code_verifier=$VERIFIER" | jq -r .access_token)

# 2) 注册客户端:
curl -X POST http://localhost:5555/oauth2/register \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"client_name": "my-terraform-managed-app",
"client_type": "CONFIDENTIAL",
"token_endpoint_auth_method": "client_secret_basic",
"redirect_uris": ["https://app.example.com/callback"],
"grant_types": ["authorization_code", "refresh_token"],
"post_logout_redirect_uris": ["https://app.example.com/"]
}'

请求字段:

字段必填说明
client_name是展示名,显示在登录 / 授权确认页。
client_type否CONFIDENTIAL(默认)或 PUBLIC。
token_endpoint_auth_method否none / client_secret_basic / client_secret_post。按类型默认:PUBLIC → none(唯一选项),CONFIDENTIAL → client_secret_basic。之后令牌端点会持续强制(F-017)。
redirect_urisCONFIDENTIAL 必填数组。开发环境外必须 https://(回环地址豁免;开发环境可用 auth.allow_http_redirect_uri 放开)。授权时精确字符串匹配。
grant_types否authorization_code、refresh_token、client_credentials 的子集;默认 ["authorization_code"]。
post_logout_redirect_uris否专用登出目标(同套 scheme 策略)。非空时对 end_session 权威生效——登录合法但未登记为登出目标的 URI 会被拒绝;留空则回退到登录回调列表。

201 Created 响应回显注册内容并附加生成的凭据:client_id、 client_secret、client_id_issued_at、client_secret_expires_at (0——密钥不会自动过期,需显式轮换)。client_secret 仅显示一次—— 请立即存入密钥管理服务;没有读回路径,只有重置 / 轮换。注册动作以 client_registered 计入审计(成功与失败皆记)。

已有注册的管理(RFC 7592 读取 / 更新 / 删除)未实现——请改用管理端 客户端 API(/api/admin/clients)。

2. 将 OIDC 库指向 Fulla​

Discovery 一步到位:

https://your-fulla.example/.well-known/openid-configuration

标准配置:授权端点 /oauth2/authorize、令牌端点 /oauth2/token、 JWKS /.well-known/jwks.json、scope openid profile email。

3. 用户登录​

授权码 + PKCE(PUBLIC 与 CONFIDENTIAL 客户端均可):

GET /oauth2/authorize?
client_id=YOUR_CLIENT_ID
&redirect_uri=https://your-app.example/callback
&response_type=code
&scope=openid profile email
&state=<random>
&code_challenge=<S256(verifier)>
&code_challenge_method=S256

在 /oauth2/token 交换 code,用 JWKS 验证 id_token, 并从 /oauth2/userinfo 读取资料 claims。

4. 自动化(无用户在场)​

脚本与服务间集成不走用户登录——设备流与 client_credentials 见 使用 Fulla 做自动化。

5. 运维要点​

  • 轮换密钥(门户 → 我的应用 → 轮换密钥)会使旧密钥立即失效。
  • 删除应用会吊销其用户授权并停止令牌签发。
  • 管理员可停用滥用应用;停用后的客户端校验立即失败。