symfony/security-http
Symfony Security HTTP integrates the Security Core with HTTP: firewalls, authenticators, and request/response handling to protect parts of your app and authenticate users. Install via composer require symfony/security-http.
To integrate symfony/security-http into a Laravel application, start by installing the package via Composer:
composer require symfony/security-http
Configure Security Bundle (if not using Laravel's built-in auth):
Laravel already integrates Symfony's security components, so you can leverage security-http directly in your config/auth.php or custom security configuration.
Define a Firewall (e.g., in app/Providers/AuthServiceProvider.php):
use Symfony\Component\HttpFoundation\RequestMatcher;
use Symfony\Component\Security\Http\Firewall;
public function boot()
{
$firewall = new Firewall(
$this->createAuthenticator(),
new RequestMatcher('/login', ['GET', 'POST'])
);
$firewall->addListener('authentication.failure', [$this, 'onAuthenticationFailure']);
$this->app['security.firewall_map']->add('main', $firewall);
}
Create a Custom Authenticator (e.g., app/Services/CustomAuthenticator.php):
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
class CustomAuthenticator extends AbstractAuthenticator
{
public function supports(Request $request): ?bool
{
return $request->isMethod('POST') && $request->getPathInfo() === '/login';
}
public function authenticate(Request $request): Passport
{
$email = $request->request->get('email');
$password = $request->request->get('password');
if (null === $user = $this->userProvider->loadUserByIdentifier($email)) {
throw new AuthenticationException('Invalid credentials.');
}
return new Passport(new UserPasswordCredentials($email, $password), new RememberMeCookie());
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
return new RedirectResponse('/dashboard');
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
{
return new RedirectResponse('/login?error=' . urlencode($exception->getMessage()));
}
}
Register the Authenticator in AuthServiceProvider:
protected function createAuthenticator()
{
return new CustomAuthenticator($this->app->make(UserProviderInterface::class));
}
auth facade or AuthenticatesUsers trait for simpler setups.FormLoginAuthenticator, RememberMeAuthenticator, or OidcAuthenticator.AbstractAuthenticator to handle login requests. Override supports(), authenticate(), and success/failure callbacks.TokenInterface (e.g., UsernamePasswordToken) to represent authenticated users.Passport object for secure transmission.[IsGranted] for method-level authorization:
#[IsGranted('ROLE_ADMIN')]
public function adminDashboard(): Response
{
return new Response('Welcome, Admin!');
}
VoterInterface for custom authorization logic:
class PostVoter implements VoterInterface
{
public function vote(AuthenticatedToken $token, mixed $subject, array $attributes): bool
{
return $token->getUser()->isOwnerOf($subject);
}
}
RequestMatcher to apply firewalls to specific routes or patterns:
$matcher = new RequestMatcher('/admin', ['GET']);
$firewall = new Firewall($authenticator, $matcher);
RememberMeAuthenticator:
$firewall->addListener('remember_me', new RememberMeListener($this->rememberMeServices));
CsrfTokenManager for form protection:
#[IsCsrfTokenValid('authenticate')]
public function login(Request $request): Response
{
// Handle login
}
$oidcAuthenticator = new OidcAuthenticator(
$clientId,
$clientSecret,
$issuerUrl,
$userProvider
);
$firewall->addListener('authentication', $oidcAuthenticator);
Auth::attempt() alongside Symfony's UserProviderInterface for hybrid setups.AuthenticationListener) to Laravel middleware for seamless integration.AuthenticationUtils to test authentication flows:
$utils = new AuthenticationUtils();
$authenticationException = $utils->getLastAuthenticationError();
CSRF Bypass in HEAD Requests
#[IsCsrfTokenValid] checks (fixed in v8.0.12+).Lazy User Serialization
UserInterface::getRoles() to trigger loading.Impersonation Quirks
ImpersonatingToken and ensure proper token persistence.OIDC Discovery with Multiple HttpClients
HttpClient instances are used.HttpClient for OIDC or use the security:oidc-token:generate command.Empty JSON Login Credentials
BadCredentialsException (fixed in v8.0.9+).security.authentication.failure for debugging:
$this->app->make('event.dispatcher')->addListener(
'security.authentication.failure',
function (AuthenticationFailureEvent $event) {
\Log::error('Auth failure: ' . $event->getException()->getMessage());
}
);
TokenStorage to inspect the current user/token:
$token = $this->app['security.token_storage']->getToken();
\Log::info('Current user:', $token->getUser());
Trusted Hosts for CAS
trusted_hosts configuration (enforced in v8.0.12+).trusted_hosts: ['yourdomain.com'] in your CAS authenticator.Base URL Preservation
HttpUtils::createRequest() may strip base URLs (fixed in v8.0.11+).Context object includes the base URL.Deprecated Constructors
RememberMeDetails) are deprecated.RememberMeDetails::create()).Custom Authenticators
AbstractAuthenticator or implement AuthenticatorInterface for bespoke flows (e.g., JWT, API keys).Voters and Access Control
VoterInterface for granular permissions or override AccessDecisionManager.Token Providers
TokenProviderInterface implementations for stateless tokens (e.g., JWT).Event Listeners
How can I help you explore Laravel packages today?