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 Extra Bundle Laravel Package

jms/security-extra-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add via Composer:

    composer require jms/security-extra-bundle
    

    Enable in config/bundles.php:

    return [
        // ...
        JMS\SecurityExtraBundle\JMSSecurityExtraBundle::class => ['all' => true],
    ];
    
  2. First Use Case: Role-Based Access Control (RBAC) Secure a controller method with @Security("has_role('ROLE_ADMIN')"):

    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
    
    class AdminController extends Controller
    {
        /**
         * @Security("has_role('ROLE_ADMIN')")
         */
        public function dashboard()
        {
            return $this->render('admin/dashboard.html.twig');
        }
    }
    
  3. Key Configuration Update config/packages/security.yaml:

    security:
        access_control:
            - { path: ^/admin, roles: ROLE_ADMIN }
        # Enable annotations (if using SensioFrameworkExtraBundle)
        enable_authenticator_manager: true
    

Implementation Patterns

Common Workflows

  1. Annotation-Based Security

    • Method-Level Security: Use @Security for granular control.
      /**
       * @Security("has_role('ROLE_EDITOR') or has_role('ROLE_ADMIN')")
       */
      public function edit(Post $post) { ... }
      
    • Class-Level Security: Apply to all methods in a controller.
      /**
       * @Security("has_role('ROLE_USER')")
       */
      class UserController extends Controller { ... }
      
  2. Voter Integration

    • Create custom voters (e.g., PostVoter) and register them in security.yaml:
      security:
          access_decision_manager:
              strategy: affirmative
          voters:
              - JMS\SecurityExtraBundle\Security\Authorization\Voter\PostVoter
      
    • Use in annotations:
      /**
       * @Security("is_granted('EDIT', post)")
       */
      public function edit(Post $post) { ... }
      
  3. CSRF Protection

    • Enable globally in security.yaml:
      security:
          csrf_protection:
              enabled: true
      
    • Exclude routes (e.g., API endpoints) via @CSRFProtect:
      /**
       * @CSRFProtect(false)
       */
      public function apiWebhook() { ... }
      
  4. Two-Factor Authentication (2FA)

    • Use JMS\SecurityExtraBundle\Security\Authentication\Token\TwoFactorToken for custom 2FA flows.
    • Example: Extend AbstractGuardAuthenticator to handle 2FA tokens.
  5. Event Listeners

    • Listen to security.interactive_login or security.authentication.success:
      public function onAuthenticationSuccess(AuthenticationSuccessEvent $event)
      {
          $user = $event->getAuthenticationToken()->getUser();
          // Log or trigger actions (e.g., send welcome email)
      }
      
    • Register in services.yaml:
      services:
          App\EventListener\SecurityListener:
              tags:
                  - { name: kernel.event_listener, event: security.authentication.success }
      

Integration Tips

  1. Symfony Flex Compatibility

    • Works seamlessly with Symfony 4/5/6. No manual bundle registration needed in AppKernel.php.
  2. Doctrine Integration

    • Use JMS\SecurityExtraBundle\Security\Authorization\Voter\ORMVoter for object-level permissions:
      /**
       * @Security("is_granted('DELETE', post)")
       */
      public function delete(Post $post) { ... }
      
    • Requires Doctrine ORM and proper entity metadata (e.g., @ORM\HasLifecycleCallbacks).
  3. API Security

    • Combine with lexik/jwt-authentication-bundle for token-based auth:
      security:
          access_control:
              - { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
      
  4. Testing

    • Mock voters or use SecurityContext in PHPUnit:
      $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
      $this->container->get('security.token_storage')->setToken($token);
      

Gotchas and Tips

Pitfalls

  1. Annotation Parsing Issues

    • Problem: @Security annotations ignored.
    • Fix: Ensure sensio/framework-extra-bundle is installed and annotations: true in framework.yaml:
      framework:
          router:
              utf8: true
          annotations: true
      
  2. Voter Precedence

    • Problem: Voters evaluated in arbitrary order.
    • Fix: Use access_decision_manager to define strategy (e.g., unanimous for strict checks):
      security:
          access_decision_manager:
              strategy: unanimous
      
  3. CSRF Token Mismatch

    • Problem: InvalidCsrfTokenException in forms.
    • Fix: Regenerate tokens on form reload or use @CSRFToken in Twig:
      {{ form_start(form, { attr: { 'data-csrf-token': app.request.csrfToken } }) }}
      
  4. Deprecated Features

    • Problem: JMS\SecurityExtraBundle\Security\Authorization\Voter\RoleVoter is deprecated.
    • Fix: Use Symfony’s built-in RoleVoter or migrate to custom voters.
  5. Performance with ORM Voters

    • Problem: N+1 queries in isGranted('EDIT', entity).
    • Fix: Use @ORM\QueryAnnotation or DQL in voters:
      public function supportsAttribute($attribute, $subject)
      {
          return $attribute === 'EDIT' && $subject instanceof Post;
      }
      
      public function vote(AuthenticationToken $token, $subject, array $attributes)
      {
          $user = $token->getUser();
          return $user->getId() === $subject->getAuthorId();
      }
      

Debugging Tips

  1. Enable Security Debugging

    • Add to config/packages/dev/security.yaml:
      security:
          debug: true
      
    • Check logs for SECURITY level messages.
  2. Dump Voters

    • Temporarily add to a controller:
      public function debugVoters()
      {
          $dm = $this->container->get('security.access_decision_manager');
          dump($dm->getDecisionManagers());
      }
      
  3. Test Voters in Isolation

    • Use AccessDecisionManager directly:
      $dm = $this->container->get('security.access_decision_manager');
      $token = new UsernamePasswordToken($user, null, 'main', ['ROLE_USER']);
      $result = $dm->decide($token, ['ROLE_ADMIN'], ['POST']);
      

Extension Points

  1. Custom Voters

    • Extend AbstractVoter:
      class CustomVoter extends AbstractVoter
      {
          public function supportsAttribute($attribute)
          {
              return $attribute === 'CUSTOM_ACTION';
          }
      
          protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
          {
              return AccessDecisionManagerInterface::ACCESS_GRANTED;
          }
      }
      
  2. Override Access Control

    • Create a custom AccessControlList:
      security:
          access_control:
              - { path: ^/custom, roles: ROLE_CUSTOM }
      
  3. Event Subscribers

    • Extend SecurityEvents (e.g., AUTHENTICATION_SUCCESS):
      public static function getSubscribedEvents()
      {
          return [
              SecurityEvents::AUTHENTICATION_SUCCESS => 'onAuthenticationSuccess',
          ];
      }
      
  4. Token Factories

    • Implement TokenFactoryInterface for custom authentication tokens:
      class TwoFactorTokenFactory implements TokenFactoryInterface
      {
          public function createToken(UserInterface $user, string $firewallName, array $options)
          {
              return new TwoFactorToken($user, $firewallName, $options);
          }
      }
      
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky