Skip to content

feat(auth): add Feishu OAuth2 login provider - #696

Open
yhd4711499 wants to merge 2 commits into
iflytek:mainfrom
yhd4711499:feat/feishu-oauth-login
Open

feat(auth): add Feishu OAuth2 login provider#696
yhd4711499 wants to merge 2 commits into
iflytek:mainfrom
yhd4711499:feat/feishu-oauth-login

Conversation

@yhd4711499

Copy link
Copy Markdown

What

Adds Feishu (飞书/Lark) as an OAuth2 login provider alongside GitHub and GitLab. When OAUTH2_FEISHU_CLIENT_ID/OAUTH2_FEISHU_CLIENT_SECRET are configured, the login page automatically shows a Feishu button (the provider catalog is config-driven).

Why

Enterprise deployments need Feishu SSO. This was implemented and verified end-to-end against a real Feishu self-built app (QR login → callback → account provisioning → re-login dedup).

How

Feishu deviates from standard OAuth2, so the Spring oauth2Login pipeline is reused with three targeted customizations:

  • Authorize endpoint: Feishu requires app_id instead of client_id and does not accept a scope parameter (scopes are configured on the open-platform app). SkillHubOAuth2AuthorizationRequestResolver rebuilds the authorization URI for the feishu registration only.
  • Userinfo envelope: Feishu returns {code, msg, data} with errors reported as HTTP 200, which DefaultOAuth2UserService cannot consume. New ProviderOAuth2UserService extension point + FeishuOAuth2UserService unwrap data into flat attributes; OAuthLoginFlowService selects the loader per registrationId (GitHub/GitLab unchanged).
  • Token endpoint: uses client_secret_post.
  • Identity: binds on open_id (stable per app); union_id is kept in extra for potential cross-app migration. Email prefers enterprise_email over email; users without email are denied under the EMAIL_DOMAIN access policy (documented).

Also includes:

  • web/public/feishu-logo.svg (the only frontend change; button rendering/i18n adapt automatically)
  • .env.release.example and docs/03-authentication-design.md updates (Feishu as the non-standard provider integration template)
  • Separate fix: SKILLHUB_TRUST_FORWARDED_PROTO was undefined in docker-compose.staging.yml, breaking make staging with an nginx "unknown variable" error (pre-existing on main)

Testing

  • ./mvnw -pl skillhub-auth -am test: green (new FeishuOAuth2UserServiceTest, FeishuClaimsExtractorTest, resolver app_id/no-scope assertions)
  • make typecheck-web, make lint-web: green
  • make staging: green after the compose env fix
  • E2E with a real Feishu app: login button visible, redirect carries app_id, callback provisions the account (display name + avatar synced), second login reuses the same binding (1 binding / 1 user)
  • Note: ApiAccessDeniedHandlerTest has 2 pre-existing locale-dependent failures on this machine (fails on clean HEAD too, unrelated to this change)

Impact

  • No breaking changes; Feishu stays hidden until real credentials are configured (placeholder client-id is filtered by AuthMethodCatalog)
  • Operators: set OAUTH2_FEISHU_CLIENT_ID / OAUTH2_FEISHU_CLIENT_SECRET, grant contact:user.base:readonly + contact:user.email:readonly on the app, and register <base-url>/login/oauth2/code/feishu as a redirect URL

Feishu deviates from standard OAuth2: the authorize endpoint requires
app_id instead of client_id, userinfo returns a {code, msg, data}
envelope with errors reported as HTTP 200, and the token endpoint uses
client_secret_post. Reuse the Spring oauth2Login pipeline and override
only the userinfo loading step via a ProviderOAuth2UserService extension
point, keeping GitHub/GitLab behavior unchanged. Bindings use open_id
as subject; union_id is kept in extra for future cross-app migration.
The nginx template references this variable and envsubst leaves
undefined variables untouched, causing nginx to fail with
'unknown skillhub_trust_forwarded_proto variable' when the staging
web container starts.
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants