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

atoolo/security-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require atoolo/security-bundle
    

    Ensure your config/bundles.php includes the bundle:

    return [
        // ...
        Atoolo\SecurityBundle\AtooloSecurityBundle::class => ['all' => true],
    ];
    
  2. Configuration: Copy the default security configuration from the bundle's Resources/config/security.yaml to your project's config/packages/security.yaml. Key sections to review:

    • providers (user loading strategy)
    • firewalls (entry points, authentication methods)
    • role_hierarchy (role inheritance)
    • access_control (route-based permissions)
  3. First Use Case: Secure a route using role-based access:

    # config/packages/security.yaml
    access_control:
        - { path: ^/admin, roles: ROLE_ADMIN }
    

    Then annotate your controller:

    use Symfony\Component\Security\Http\Attribute\IsGranted;
    
    class AdminController {
        #[IsGranted('ROLE_ADMIN')]
        public function dashboard(): Response { ... }
    }
    
  4. User Management: The bundle integrates with IES CMS for role/user management. Use the UserProfile interface to extend user data:

    use Atoolo\SecurityBundle\Model\UserProfile;
    
    class CustomUser implements UserProfile {
        // Implement required methods
    }
    

Implementation Patterns

Core Workflows

1. Authentication Flow

  • Form Login: Configure in security.yaml:

    firewalls:
        main:
            form_login:
                login_path: app_login
                check_path: app_login_check
                default_target_path: dashboard
    

    Create a login controller:

    use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
    
    class LoginController {
        public function login(AuthenticationUtils $authenticationUtils): Response {
            $error = $authenticationUtils->getLastAuthenticationError();
            return $this->render('security/login.html.twig', ['error' => $error]);
        }
    }
    
  • JWT Authentication (via LexikBundle): Enable in security.yaml:

    firewalls:
        api:
            pattern: ^/api
            stateless: true
            jwt: ~
    

2. Role Management

  • Dynamic Roles: Use the role_hierarchy to define inheritance:

    role_hierarchy:
        ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
        ROLE_ADMIN:        ROLE_USER
    

    Assign roles via IES CMS or programmatically:

    $user->addRole('ROLE_EDITOR');
    $user->setRoles(['ROLE_USER', 'ROLE_EDITOR']); // Overwrites existing roles
    
  • Custom Role Voter: Extend the bundle's voter system:

    use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
    
    class CustomRoleVoter implements VoterInterface {
        public function supports(string $attribute, $subject): bool { ... }
        public function vote(..., string $attribute, mixed $subject): int { ... }
    }
    

    Register as a service with the security.voter tag.

3. User Providers

  • Database Provider: Configure in security.yaml:
    providers:
        app_user_provider:
            entity: { class: App\Entity\User, property: email }
    
    Use the UserProfile interface to add CMS-managed fields:
    class User implements UserInterface, UserProfile {
        public function getProfileField(string $fieldName): ?string { ... }
        public function setProfileField(string $fieldName, ?string $value): void { ... }
    }
    

4. Password Handling

  • Password Updater: Use the bundle's PasswordUpdater service:
    use Atoolo\SecurityBundle\Service\PasswordUpdater;
    
    $updater = $this->container->get(PasswordUpdater::class);
    $updater->updatePassword($user, 'newPassword123!');
    

5. Canonical Host

  • Multi-Tenant Security: Use the CanonicalHostService to enforce host-based access:
    use Atoolo\SecurityBundle\Service\CanonicalHostService;
    
    $hostService = $this->container->get(CanonicalHostService::class);
    if (!$hostService->isCanonicalHost($request->getHost())) {
        throw new AccessDeniedException('Invalid host');
    }
    

Integration Tips

Laravel-Specific Adaptations

  1. Service Container: Bind the bundle's services to Laravel's container in AppServiceProvider:

    public function register(): void {
        $this->app->bind(
            Atoolo\SecurityBundle\Service\PasswordUpdater::class,
            fn($app) => new \Atoolo\SecurityBundle\Service\PasswordUpdater(
                $app->make('security.password_hasher'),
                $app->make('security.user_checker')
            )
        );
    }
    
  2. Middleware: Convert Symfony's security middleware to Laravel:

    // app/Http/Middleware/Authenticate.php
    use Atoolo\SecurityBundle\Security\Authentication\AuthenticationManager;
    
    public function handle(Request $request, Closure $next) {
        $authManager = app(AuthenticationManager::class);
        $token = $authManager->authenticate($request);
        if ($token) {
            auth()->setUser($token->getUser());
        }
        return $next($request);
    }
    
  3. Routing: Use Laravel's route middleware for access control:

    Route::get('/admin', function () {
        // ...
    })->middleware(['auth', 'role:admin']);
    
  4. Events: Listen to Symfony's security events via Laravel's event system:

    Event::listen(SecurityEvents::AUTHENTICATION_SUCCESS, function ($event) {
        // Convert Symfony event to Laravel
        auth()->login($event->getAuthenticationToken()->getUser());
    });
    

CMS Integration

  • IES User Sync: Use the UserProfile interface to sync CMS-managed fields:

    class User implements UserInterface, UserProfile {
        public function getProfileField(string $fieldName): ?string {
            return $this->iesProfileData[$fieldName] ?? null;
        }
    
        public function setProfileField(string $fieldName, ?string $value): void {
            $this->iesProfileData[$fieldName] = $value;
            $this->save(); // Persist to DB
        }
    }
    
  • Role Sync: Implement a cron job to sync roles from IES:

    use Atoolo\SecurityBundle\Service\RoleManager;
    
    $roleManager = app(RoleManager::class);
    $roleManager->syncRolesFromCMS();
    

Gotchas and Tips

Pitfalls

  1. Symfony vs. Laravel Quirks:

    • Service IDs: The bundle uses Symfony's service IDs (e.g., security.user_checker). In Laravel, bind these explicitly to avoid ServiceNotFoundException.
    • Event Dispatcher: Symfony's EventDispatcher is not Laravel's Dispatcher. Use the SymfonyEventDispatcher facade or create a bridge:
      $dispatcher = new SymfonyEventDispatcher(app('events'));
      
  2. Password Hashing:

    • The bundle assumes Symfony's PasswordHasherInterface. In Laravel, use:
      $hasher = app(\Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface::class);
      
    • Deprecation: getSalt() is removed in Symfony 6+. Use getSalt() from the user object or rely on Symfony's auto-salt generation.
  3. Role Hierarchy:

    • Spaces in role names (e.g., ROLE_SUPER ADMIN) may cause issues. Trim roles in a voter:
      $role = trim($role);
      
  4. Canonical Host:

    • The CanonicalHostService requires a configured canonical_host in security.yaml. If missing, it defaults to null, bypassing checks.
  5. JWT Integration:

    • LexikBundle's JWT requires a user_provider key in security.yaml. Ensure it matches your Laravel user provider:
      lexik_jwt: ~
      providers:
          lexik_jwt:
              entity: { class: App\Models\User, property: email }
      
  6. User Provider Conflicts:

    • If using Laravel's Authenticatable, ensure the UserInterface methods (getRoles(), eraseCredentials()) are implemented. The bundle expects Symfony's UserInterface.

Debugging Tips

  1. Authentication Failures:
    • Enable Symfony's debug mode in Laravel:
      $this->app->make('debug')->setDebug(true);
      
    • Check the `
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle