kleegroup/franceconnect-bundle
Symfony bundle for integrating FranceConnect authentication into PHP applications. It simplifies the OAuth2 authorization flow, callback handling, and retrieval of authenticated user data, making it easier to add the French government identity provider to your Symfony app.
Bottom line: release 0.8 materially changes the maintenance story and softens one hard blocker, but not the architecture verdict. This is now a Symfony 6 bundle on PHP 8.1+, not a Symfony 3 artifact — so it is no longer dead code on an EOL framework. It is still a Symfony Bundle, and Laravel has no bundle/container-extension/firewall-authenticator concept, so none of the integration surface transfers. Recommendation is unchanged in direction: re-implement as a Laravel Socialite/league/oauth2-client provider; the bundle remains useful as a specification reference (endpoint URLs, scope set, userinfo→attribute mapping, logout/revocation, FC error codes) and is now a somewhat better reference because it has been touched against modern Symfony security APIs.
What changed in 0.8 (and what it means)
FlorianKlee) — the headline. Symfony 3 pins are presumably gone; PHP floor rises to ~8.1. This retires the previous "Composer resolution fails outright / PHP constraint <8.1" blocker for a Symfony host, and it means the deprecated UsernamePasswordToken / guard-era authenticator code was probably rewritten to the Symfony 5.3+/6 authenticator system. Caveat: we have PR titles only. No changelog detail, no stated constraint range, no CI/test evidence in the release notes. Treat "Symfony 6" as claimed and unverified until composer.json and the test suite are inspected.proxy_port config change (PR #5) and a doc typo (PR #2) — cosmetic; the proxy knob is mildly relevant if our egress goes through a corporate proxy, but carries no adoption weight.Architecture fit — still poor for Laravel (unchanged)
Bundle class + DI extension + Configuration tree) and Symfony Security firewall wiring have no Laravel analogue. The 0.8 Symfony 6 rewrite is, if anything, more idiomatic Symfony 6 (new authenticator system, TreeBuilder-based config) and therefore less portable as copy-paste than the old guard-era code.openid, given_name, family_name, birthdate, gender, birthplace, birthcountry, preferred_username, email, address), attribute mapping, logout/revocation handling, and FC-specific error codes. That is still worth roughly ~1 day of reading.config/services.php, credentials in env/Secrets Manager, a dedicated controller, and an fc_sub column on users.Integration feasibility — feasible, but still only as a re-implementation (on Laravel)
client_id/secret, exact-match registered redirect_uris, and FC charter/branding adherence. Multi-week external dependency.Technical risk — high, but of a different shape than before
composer audit noise from Symfony 3 CVEs should drop. This was the single largest technical objection and it is now substantially mitigated for Symfony hosts.state/nonce, PKCE, sector-identifier-derived hashed sub, FranceConnect+ / eIDAS assurance levels). A 0.8 release bumping Symfony does not evidence OIDC-migration completeness. Re-verify against current FC integration docs rather than trusting the bundle.email optional and not necessarily verified; sub can change if the sector identifier is misconfigured, silently producing duplicate accounts. Never key on email; key on fc_sub.Key questions (updated)
composer.json actually declare — a ^4.4|^5|^6 band or a hard ^6.0? Is there a CI workflow and a passing test suite backing the Symfony 6 claim? (30-minute check, gates everything else.)Stack fit
laravel/socialite (custom provider) or league/oauth2-client. Do not add kleegroup/franceconnect-bundle to a Laravel composer.json — 0.8 does not change this; the blocker is now architectural (bundle/firewall), not version resolution.Socialite::buildProvider(FranceConnectProvider::class) → callback controller → resolve/create local user by fc_sub → Auth::login(). Keep the provider stateless and config-driven; store state/nonce in shared session storage (Redis) so multi-instance deploys don't break the callback.Migration path
Compatibility
Sequencing
redirect_uri.fc_sub as the sole external key; explicit account-linking UX; tolerate absent email.access_denied, invalid_request, _error params).Maintenance
composer audit and CI dependency scanning. If re-implemented on Laravel: maintenance collapses to a small provider class + OIDC library updates — still the cheaper path by a wide margin, and still the main argument for re-implementation.Support
Scaling
Failure modes
state/nonce mismatch from lost sessions on multi-instance deploys → intermittent, hard-to-reproduce callback failures.redirect_uri drift between environments → FC rejects before our code runs.sub → duplicate accounts and orphaned data.address when unnecessary) → data-minimisation non-compliance and accreditation risk.Ramp-up
How can I help you explore Laravel packages today?