feat(auth): add Feishu OAuth2 login provider - #696
Conversation
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.
Signed-off-by: yhd <yhd4711499@live.com>
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. Signed-off-by: yhd <yhd4711499@live.com>
93ef04a to
0bfedc4
Compare
Replace the hand-drawn approximation with the official Feishu/Lark tri-color brand mark (teal/blue/navy), matching the feishu.cn logo. Source: homarr-labs/dashboard-icons. Signed-off-by: yhd <yhd4711499@live.com>
There was a problem hiding this comment.
Requesting changes for two protocol/correctness issues:
-
The custom resolver targets
https://open.feishu.cn/open-apis/authen/v1/authorize, replacesclient_idwithapp_id, and removesscope. Feishu's current server-side OAuth documentation specifieshttps://accounts.feishu.cn/open-apis/authen/v1/authorize,client_id, and optionalscope, and recommends standard OAuth clients. Please switch to the current endpoint and standard parameters, or provide an official supported-flow reference and tests showing why the legacyapp_idflow is required. -
FeishuClaimsExtractormarks every returned email as verified. Feishu's user-info documentation states that email and mobile fields are administrator-imported and are not verified with the user in real time. Please keepemailVerifiedfalse unless an independent verification signal exists, and update the tests.
The authentication module suite passes locally (126 tests), so these findings concern protocol compatibility and claim semantics rather than unit-test regressions.
Addresses review on PR iflytek#696: 1. The authorize step now uses the currently documented endpoint https://accounts.feishu.cn/open-apis/authen/v1/authorize with standard OAuth2 parameters (client_id, optional scope), so the legacy app_id/no-scope URI rewrite in SkillHubOAuth2AuthorizationRequestResolver is removed. The authorize host is overridable via OAUTH2_FEISHU_AUTHORIZE_URI; token and userinfo endpoints stay on OAUTH2_FEISHU_BASE_URI. 2. FeishuClaimsExtractor no longer claims emailVerified: Feishu emails are admin-imported and carry no real-time verification signal, so emailVerified is always false. EMAIL_DOMAIN policy matches the email domain only and is unaffected. Signed-off-by: yhd <yhd4711499@live.com>
What
Adds Feishu (飞书/Lark) as an OAuth2 login provider alongside GitHub and GitLab. When
OAUTH2_FEISHU_CLIENT_ID/OAUTH2_FEISHU_CLIENT_SECRETare 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
oauth2Loginpipeline is reused with three targeted customizations:app_idinstead ofclient_idand does not accept ascopeparameter (scopes are configured on the open-platform app).SkillHubOAuth2AuthorizationRequestResolverrebuilds the authorization URI for thefeishuregistration only.{code, msg, data}with errors reported as HTTP 200, whichDefaultOAuth2UserServicecannot consume. NewProviderOAuth2UserServiceextension point +FeishuOAuth2UserServiceunwrapdatainto flat attributes;OAuthLoginFlowServiceselects the loader per registrationId (GitHub/GitLab unchanged).client_secret_post.open_id(stable per app);union_idis kept inextrafor potential cross-app migration. Email prefersenterprise_emailoveremail; 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.exampleanddocs/03-authentication-design.mdupdates (Feishu as the non-standard provider integration template)SKILLHUB_TRUST_FORWARDED_PROTOwas undefined indocker-compose.staging.yml, breakingmake stagingwith an nginx "unknown variable" error (pre-existing on main)Testing
./mvnw -pl skillhub-auth -am test: green (newFeishuOAuth2UserServiceTest,FeishuClaimsExtractorTest, resolver app_id/no-scope assertions)make typecheck-web,make lint-web: greenmake staging: green after the compose env fixapp_id, callback provisions the account (display name + avatar synced), second login reuses the same binding (1 binding / 1 user)ApiAccessDeniedHandlerTesthas 2 pre-existing locale-dependent failures on this machine (fails on clean HEAD too, unrelated to this change)Impact
AuthMethodCatalog)OAUTH2_FEISHU_CLIENT_ID/OAUTH2_FEISHU_CLIENT_SECRET, grantcontact:user.base:readonly+contact:user.email:readonlyon the app, and register<base-url>/login/oauth2/code/feishuas a redirect URL