Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Sonata Oauth2 Login Bundle Laravel Package

silasjoisten/sonata-oauth2-login-bundle

Symfony bundle that adds OAuth2 login to Sonata Admin, letting users authenticate through external providers instead of local credentials. Configure your OAuth2 provider and integrate single sign-on into the Sonata admin panel with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle (not Laravel) that bolts OAuth2 login onto a Sonata Admin panel — it lets admins sign in with Google/GitHub/Azure/etc. instead of, or alongside, the standard Sonata login form.

  1. composer require silasjoisten/sonata-oauth2-login-bundle:^6.1
  2. Register Sonata\OAuth2LoginBundle\SonataOAuth2LoginBundle in config/bundles.php
  3. Import the bundle routes (typically @SonataOAuth2LoginBundle/Resources/config/routing.yaml) in config/routes.yaml
  4. Create an OAuth app in each provider's console and copy the client ID/secret
  5. Add a providers: block to config/packages/sonata_oauth2_login.yaml with the client credentials, scopes, and an absolute redirect_uri pointing at the bundle's check route
  6. Wire the firewall in security.yaml, run bin/console debug:router | grep -i oauth2 to confirm the redirect/check routes are registered

First use case: replace the Sonata login page with a "Sign in with Google" button for a single provider, with the OAuth callback resolving to an existing Sonata user by email. Get that one-provider flow working end to end before adding a second provider or auto-provisioning.

Look first at: bin/console config:dump-reference sonata_oauth2_login — the README lags behind the config tree, and this is the authoritative list of keys for the installed version.

Implementation Patterns

One provider key = one route pair. Each entry under providers: generates its own redirect and check route keyed by name (google, github, …). Adding a provider is config-only — no controller code — so model the provider list as environment-specific config rather than hardcoding it.

Keep the callback public, keep /admin protected. The OAuth redirect/check routes must be reachable anonymously, while /admin stays behind ROLE_ADMIN/ROLE_SONATA_ADMIN. Test the access_control ordering, since Symfony matches rules top-down and a broad ^/ rule will swallow the callback.

Coexist with form login. The usual pattern is a dual login page: the Sonata form for local/break-glass accounts, plus OAuth buttons. Keeping at least one password-based super-admin is worth the friction — it is your recovery path if a provider tenant or client secret is misconfigured.

Separate OAuth apps per environment. admin.example.com in prod, admin.staging.example.com in staging, localhost:8000 in dev. Put client IDs/secrets in .env and reference them via %env(...)% rather than committing YAML with secrets.

Provisioning is the real design decision. Decide up front whether OAuth users must already exist (lookup by email, reject unknown) or are auto-created on first login. For an admin panel, the lookup-only path is usually correct: it means an attacker who controls an account at the IdP still cannot get into Sonata unless you pre-created the user. If you do auto-create, gate it on a verified email domain and assign the most limited role that renders the dashboard.

Never derive admin roles from IdP claims. Map OAuth identity → local user → local roles. Group/claim mapping is tempting but hands your authorization model to whoever administers the customer's Google Workspace.

Customize via decoration, not forks. The user resolution/creation step and the login templates are the two extension points you will actually need. Decorate the relevant service (or override the template) in services.yaml so security patches to the bundle stay mergeable.

Testing. For feature tests, stub the HTTP client used by the underlying OAuth2 client so the token exchange returns a canned identity, then assert the resulting authenticated user and roles. Asserting on the redirect URL alone misses the provisioning logic, which is where bugs live.

Gotchas and Tips

  • redirect_uri mismatch is the #1 failure. Scheme, host, port, trailing slash, and path must match the provider console byte-for-byte. The provider returns a generic redirect_uri_mismatch before your app logs anything — always compare the URL in the browser's address bar against the console entry first.
  • Reverse proxies break the callback URL. Behind a load balancer, Symfony generates http:// from X-Forwarded-* unless you configure framework.trusted_proxies and trusted_headers. Symptom: infinite bounce between provider and app with no error.
  • 6.1.0 drops Twig ^2.0 support. This is a minor version bump with a dependency removal. If you are still on Twig 2 (or on a Symfony version whose constraints require it), Composer will silently resolve you to 6.0.x — composer why-not silasjoisten/sonata-oauth2-login-bundle 6.1.0 will show the conflicting package. Twig 2 is EOL, so plan the upgrade to Twig 3 rather than pinning the bundle.
  • 6.1.0 also only updates CI/GitHub Action dependencies (PR #112) — no runtime behaviour change there. Treat 6.1.0 as a maintenance release whose only actionable item is the Twig constraint.
  • Missing email. GitHub returns a null/placeholder email unless you request the user:email scope and handle the /user/emails endpoint. If you key users by email, this silently fails for a subset of accounts.
  • Clearing cache after config changes. Bundle config is compiled into the container; bin/console cache:clear in the right --env before concluding that a config key "isn't being picked up".
  • Debugging sequence: debug:router → debug:config sonata_oauth2_login → check the profiler's security panel for the token/roles actually produced → then the provisioning service. Most "login loops" are a firewall ordering issue or an exception swallowed inside the check controller, which the profiler exposes but the browser does not.
  • Pin the major. Because the bundle sits directly on the authentication boundary, constrain to ^6.1 in composer.json and read the changelog before any major. Security-adjacent bundles are a poor place to float on *.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums