mirror of
https://github.com/iflytek/skillhub.git
synced 2026-09-24 00:55:35 +00:00
Adds DingTalk (钉钉) as a public sign-in option: it authenticates a SkillHub platform account and nothing more. No Organization membership, no directory sync, no Namespace grants. DingTalk deviates from standard OAuth at all three stages, one strategy each: - authorize: its endpoint wants scope=openid, but declaring that scope in configuration makes Spring treat the registration as OIDC and attach a nonce, which DingTalk rejects. The scope is added by DingTalkAuthorizationRequestCustomizer instead, keeping this a plain OAuth2 client. A test asserts the scope is present and the nonce is not. - token: credentials go in a JSON body rather than a form, handled by DingTalkTokenResponseClient. - userinfo: the token travels in x-acs-dingtalk-access-token rather than Authorization: Bearer. Subject and email semantics, which decide whether a login can reach an existing account: - unionId is the only accepted subject. DingTalk also returns openId and userId, but they must not act as fallbacks: openId is scoped per app and userId per organization, so a login falling back to either would bind a different identity than a later login carrying unionId, splitting one person across two platform accounts. - A blank or missing unionId fails the login. - emailVerified is always false. DingTalk returns the email an organization admin recorded without attesting the user controls it. The userinfo service only fetches attributes; account matching, provisioning and session creation stay with the unified identity core. The reference implementation called OAuthLoginFlowService.authenticate() from inside loadUser, which decided the account before the core's gate ran. Operational bounds match the Feishu adapter: connect and read timeouts, a 64 KB response cap, error descriptions and logs carrying only the exception class or provider error code, and no logging in the claims extractor. Unused PII is dropped rather than carried into the principal -- notably mobile and stateCode. Adds ProviderStrategyWiringTest, which loads the real application context. The unit tests call package-visible constructors and so cannot catch Spring wiring faults; a component with two constructors and no @Autowired marker unit-tests green and then fails at startup. That happened during this work. Adapted from the implementation in #467 by @konglong87, re-extracted onto current main with the subject, structure and bounds changes above. Part of R1-A2 (public Provider adapters) per openspec/changes/enterprise-identity-platform/rollout-plan.md. Co-authored-by: konglong87 <konglong87@users.noreply.github.com> Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com> |
||
|---|---|---|
| .. | ||
| docker-entrypoint.d | ||
| e2e | ||
| public | ||
| src | ||
| .browserslistrc | ||
| .dockerignore | ||
| .eslintrc.cjs | ||
| base-path-config.test.ts | ||
| base-path-config.ts | ||
| components.json | ||
| Dockerfile | ||
| index.html | ||
| LANDING_PAGE_REDESIGN.md | ||
| nginx.conf.template | ||
| package.json | ||
| playwright.config.ts | ||
| playwright.smoke.config.ts | ||
| pnpm-lock.yaml | ||
| postcss.config.js | ||
| PREVIEW.md | ||
| runtime-config.js.template | ||
| tailwind.config.ts | ||
| TODO.md | ||
| tsconfig.json | ||
| vite.config.ts | ||