Weave Code
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

Security Core Laravel Package

symfony/security-core

Symfony Security Core provides the foundation for authentication tokens, roles, voters, role hierarchies, and access decision management. Use it to build flexible authorization logic decoupled from user providers and integrate fine-grained access checks into apps.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup in Laravel

To integrate symfony/security-core into a Laravel project, start by installing the package:

composer require symfony/security-core

First Use Case: Basic Authentication Check

Leverage the AccessDecisionManager to validate user permissions in controllers or services:

use Symfony\Component\Security\Core\Authorization\AccessDecisionManager;
use Symfony\Component\Security\Core\Authorization\Voter\RoleVoter;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;

// In a Laravel service or controller
$accessDecisionManager = new AccessDecisionManager([
    new RoleVoter(),
]);

$user = auth()->user(); // Laravel's authenticated user
$token = new UsernamePasswordToken($user, 'main', $user->getRoles());

if (!$accessDecisionManager->decide($token, ['ROLE_ADMIN'])) {
    abort(403, 'Unauthorized');
}

Key Entry Points

  1. Authentication: Use UsernamePasswordToken or AnonymousToken for token creation.
  2. Authorization: AccessDecisionManager + RoleVoter for role-based access.
  3. User Providers: Implement UserProviderInterface for custom user loading logic.

Implementation Patterns

Workflow: Role-Based Access Control (RBAC)

  1. Define Roles: Extend Laravel’s User model with roles (e.g., ROLE_ADMIN, ROLE_EDITOR).
  2. Configure Voters: Chain RoleVoter and AuthenticatedVoter in AccessDecisionManager.
  3. Check Permissions:
    $accessDecisionManager->decide($token, ['ROLE_ADMIN']); // Returns bool
    
  4. Laravel Integration: Wrap checks in a service or middleware:
    public function handle(Request $request, Closure $next)
    {
        $user = auth()->user();
        $token = new UsernamePasswordToken($user, 'main', $user->getRoles());
        if (!$this->accessDecisionManager->decide($token, ['ROLE_ADMIN'])) {
            abort(403);
        }
        return $next($request);
    }
    

Workflow: Custom Voters

Extend VoterInterface for attribute-based checks (e.g., "can_edit_post"):

use Symfony\Component\Security\Core\Authorization\Voter\Voter;

class PostVoter extends Voter
{
    protected function supports(string $attribute, $subject): bool
    {
        return in_array($attribute, ['CAN_EDIT', 'CAN_DELETE']) && $subject instanceof Post;
    }

    protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
    {
        $user = $token->getUser();
        return $user->id === $subject->user_id; // Example logic
    }
}

Integration Tips

  • Laravel Auth: Use symfony/security-core alongside Laravel’s Auth facade for hybrid auth logic.
  • Middleware: Create middleware to centralize permission checks:
    public function handle($request, Closure $next)
    {
        if (!$this->accessDecisionManager->decide($request->user()->token, ['ROLE_USER'])) {
            abort(403);
        }
        return $next($request);
    }
    
  • Service Container: Bind AccessDecisionManager as a singleton in AppServiceProvider:
    $this->app->singleton(AccessDecisionManager::class, function () {
        return new AccessDecisionManager([new RoleVoter()]);
    });
    

Gotchas and Tips

Pitfalls

  1. Token Lifecycle:

    • Tokens are not automatically persisted across requests. Recreate them per request if needed.
    • Example: Avoid storing tokens in the session; regenerate them using the authenticated user.
  2. Role Hierarchy:

    • RoleHierarchyVoter requires explicit role inheritance configuration:
      $roleHierarchy = new RoleHierarchy([
          'ROLE_ADMIN' => ['ROLE_USER', 'ROLE_EDITOR'],
      ]);
      
    • Forgetting to configure hierarchies can lead to silent permission denials.
  3. User Providers:

    • Implement loadUserByIdentifier() in custom providers. Laravel’s User model must implement UserInterface:
      class User implements UserInterface
      {
          public function getRoles(): array { return $this->roles; }
          public function eraseCredentials() { /* ... */ }
      }
      
  4. Deprecations:

    • Avoid eraseCredentials() in Symfony 8+. Use UserInterface without it or implement a no-op method.

Debugging Tips

  • Vote Explanation: Enable voter debugging by extending AccessDecisionManager to log votes:
    $accessDecisionManager = new AccessDecisionManager([...], new DebugAccessDecisionVoter());
    
  • Token Inspection: Dump token attributes for troubleshooting:
    dd($token->getUser(), $token->getRoles(), $token->getCredentials());
    
  • Common Issues:
    • 403 Errors: Verify roles are correctly assigned to the user and token.
    • Circular Dependencies: Avoid cyclic role hierarchies (e.g., ROLE_AROLE_BROLE_A).

Extension Points

  1. Custom Attributes: Use #[IsGranted] with custom attributes (Symfony 7.3+):

    #[IsGranted('CAN_MANAGE_USERS')]
    public function sensitiveAction()
    

    Register a voter to handle CAN_MANAGE_USERS.

  2. Impersonation: Extend AbstractGuardAuthenticator to support impersonation tokens:

    $token = new UsernamePasswordToken($impersonatedUser, 'impersonate', ['ROLE_USER']);
    $this->authenticator->authenticate($request, $token);
    
  3. Performance: Cache role hierarchies if using RoleHierarchyVoter:

    $roleHierarchy = new RoleHierarchy([...], new ArrayCache());
    

Laravel-Specific Quirks

  • Auth Guard: Symfony’s TokenStorage is not directly compatible with Laravel’s Auth. Use middleware to bridge gaps:
    $token = new UsernamePasswordToken(auth()->user(), 'main', auth()->user()->getRoles());
    
  • Session Handling: Symfony’s PersistentToken is not needed in Laravel; use Laravel’s session driver instead.
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.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle