Security

← Security

Ashterix

docs(articles): English translation of From Magento to Symfony

en/articles/magento-to-symfony/data/security.md new file +83 −0

Security

The Security component answers two questions. Authentication (who you are): firewall, user provider, authenticator. Authorization (what you're allowed to do): roles, access_control and voters. You write the user classes yourself: make:user creates a User entity with UserInterface.

Symfony · config/packages/security.yaml

security:
    password_hashers:
        Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: auto
    providers:
        users:
            entity: { class: App\Entity\User, property: email }
    role_hierarchy:
        ROLE_ADMIN: [ROLE_FAQ_EDITOR]
    firewalls:
        dev:
            pattern: ^/(_profiler|_wdt|assets)/
            security: false
        main:
            lazy: true
            provider: users
            form_login:
                login_path: app_login
                check_path: app_login
                enable_csrf: true
            logout:
                path: app_logout
    access_control:
        - { path: ^/admin, roles: ROLE_FAQ_EDITOR }
        - { path: ^/account, roles: ROLE_USER }

Magento · acl.xml + ADMIN_RESOURCE

<acl>
    <resources>
        <resource id="Magento_Backend::admin">
            <resource id="Vendor_Faq::faq" title="FAQ">
                <resource id="Vendor_Faq::question_edit"
                          title="Edit questions"/>
            </resource>
        </resource>
    </resources>
</acl>
class Edit extends Action
{
    const ADMIN_RESOURCE = 'Vendor_Faq::question_edit';
}

Symfony · Voter + #[IsGranted]

final class QuestionVoter extends Voter
{
    protected function supports(string $attribute, mixed $subject): bool
    {
        return $attribute === 'QUESTION_EDIT' && $subject instanceof Question;
    }

    protected function voteOnAttribute(
        string $attribute,
        mixed $subject,
        TokenInterface $token,
        ?Vote $vote = null,
    ): bool
    {
        $user = $token->getUser();
        return $user instanceof User
            && ($user->hasRole('ROLE_ADMIN') || $subject->getAuthor() === $user);
    }
}

#[Route('/admin/questions/{id}/edit', name: 'admin_question_edit')]
#[IsGranted('QUESTION_EDIT', subject: 'question')]
public function edit(Question $question, Request $request): Response

Roles decide general access, voters decide access to a specific object ("the author can edit their own question"). Magento's ACL has no such granularity. The ?Vote $vote argument appeared in 7.3; in older versions the signature doesn't have it. For APIs you usually take the access_token authenticator or a JWT bundle instead of integration tokens.