# 2026'da Symfony Guvenlik Sistemi: Voter'lar, Firewall'lar ve Teknik Mulakat Sorulari > Symfony guvenlik sistemine kapsamli bakis: firewall'lar, voter'lar, IsGranted ozelligi, karar stratejileri, Twig 7.4 hata ayiklama ve PHP gelistiricileri icin teknik mulakat sorulari. - Published: 2026-06-18 - Updated: 2026-06-18 - Author: SharpSkill - Tags: symfony, security, php, voters, firewall, authentication, interview - Reading time: 13 min --- Symfony Security bileseni, 2026 yilinda backend gelistiricileri icin yapilan teknik mulakatlarda en sik sorgulanan ve en kapsamli degerlendirilen konularin basinda gelmektedir. Kimlik dogrulama, yetkilendirme, firewall'lar, voter'lar — her katman, senior profilleri orta seviye gelistiricilerden ayiran hassas soyutlamalar uzerine insa edilmistir. Symfony 7.4 LTS ile birlikte guvenlik sistemi, erisim kararlarina iliskin hata ayiklamanin dogrudan Twig uzerinden yapilabilmesini saglayarak gozlemlenebilirlik kazanirken, framework'un gucunu olusturan genisletilebilir mimariyi korumaya devam etmektedir. Bu makale, Symfony guvenlik sisteminin ic isleyisini derinlemesine incelemektedir: firewall yapilandirmasi, erisim token yonetimi, voter tasarimi, karar stratejileri ve guvenlik guclendirme en iyi uygulamalari. Her kavram, uretime hazir kodlarla orneklenmis ve teknik mulakatlarda sorulan sorularla iliskilendirilmistir. > **Symfony 7.4 LTS ve guvenlik yenilikleri** > > Kasim 2025'te yayinlanan ve Kasim 2029'a kadar desteklenen Symfony 7.4 LTS, 6.0 surumunden bu yana Security bileseninde yapilan onemli degisiklikleri pekistirmektedir: birlestirilmis authenticator'lar, yerel IsGranted ozelligi, Profiler ve Twig'de erisim karari hata ayiklama ve gelistirilmis voter sistemi. Bu surum, 2026 yilinda uretim projeleri ve teknik mulakatlar icin referans noktasini olusturmaktadir. ## Firewall'lar: ilk savunma hatti Symfony guvenlik sistemi, `security.yaml` dosyasinda tanimlanan firewall mimarisi uzerine kuruludur. Her firewall, kendi kimlik dogrulama ve erisim kontrolu kurallarina sahip belirli bir rota kumesi icin bir koruma cevresi tanimlar. Tanim sirasi belirleyicidir: Symfony firewall'lari sirasiyla tarar ve URL'ye uyan ilk firewall'u uygular. ```yaml # config/packages/security.yaml security: firewalls: dev: pattern: ^/(_(profiler|wdt))/ security: false api: pattern: ^/api/ stateless: true custom_authenticators: - App\Security\ApiTokenHandler main: lazy: true provider: app_user_provider form_login: login_path: app_login check_path: app_login logout: path: app_logout access_control: - { path: ^/api/public, roles: PUBLIC_ACCESS } - { path: ^/api/, roles: ROLE_API_USER } - { path: ^/admin, roles: ROLE_ADMIN } - { path: ^/dashboard, roles: ROLE_USER } ``` Bu yapilandirmada uc firewall bir arada bulunmaktadir. `dev` firewall'u, Profiler ve Web Debug Toolbar rotalari icin guvenlik sistemini tamamen devre disi birakarak gelistirme ortaminda herhangi bir mudahaleyi onlemektedir. `api` firewall'u, API endpoint'lerini ozel token tabanli durum bilgisiz (stateless) kimlik dogrulama ile korumaktadir. `main` firewall'u, web arayuzu icin oturum tabanli klasik form kimlik dogrulamasini yonetmektedir. `access_control` bolumu, kimlik dogrulamadan sonra degerlendirilen genel erisim kurallarini tanimlar. Kural sirasi kritiktir: ilk eslesen kural kazanir. `/api/public` uzerindeki `PUBLIC_ACCESS` kurali, `api` firewall'u aktif olsa bile kimlik dogrulamasi gerektirmeden erisime izin verir. Bu incelik, mulakatlarda sikca sorulan bir konudur. > **API rotalarinda security: false kullanirken dikkat** > > `security: false` bayraqi, ilgili rotalar icin Security bilesenini tamamen devre disi birakir: token yok, kullanici yok, voter yok. Bu secenek, halka acik uretim rotalarinda asla kullanilmamalidir. Belirli API rotalarinda kimlik dogrulamasi gerektirmeyen erisime izin vermek icin, firewall'u aktif tutarak `access_control` icerisinde `PUBLIC_ACCESS` kullanilmalidir. ## Stateless ve Stateful: iki kimlik dogrulama paradigmasi Stateless ve stateful kimlik dogrulama arasindaki tercih, uygulamanin guvenlik mimarisini belirler. Stateful paradigmada (main firewall'u) Symfony, kimlik dogrulama tokenini PHP oturumunda saklar. Sonraki her istek, guvenlik baglamini oturumdan yeniden olusturur ve yeniden kimlik dogrulama gerektirmez. `lazy: true` bayraqi, bu sureci optimize ederek oturumu yalnizca yetkilendirme dogrulamasi fiilen gerektiginde yukler. Stateless paradigmada (api firewall'u) her istek kendi kimlik bilgilerini tasir — Bearer token, API anahtari, JWT imzasi. Sunucu tarafinda hicbir oturum olusturulmaz. Bu model, dagitik mimariler, mikroservisler ve mobil istemciler icin dogal olarak uygundur, ancak her istegin kimlik dogrulama acisindan kendi kendine yeterli olmasini gerektirir. Bu iki paradigma arasindaki tercih, teknik bir tercihe degil mimari bir kisitlamaya dayanir. Web arayuzune sahip monolitik bir uygulama, yonetim kolayligi nedeniyle stateful modu tercih eder. Heterojen istemciler tarafindan tuketilen bir API, yatay olceklenebilirlik icin stateless modu zorunlu kilar. ## Access Token Handler: ozel kimlik dogrulama Symfony 6.2, net bir arayuz araciligiyla kimlik dogrulama token yonetimini birlestiren Access Token Handler sistemini tanitti. Bu mekanizma, eski Guard Authenticator'larin yerini alarak Security bileseniyle daha dogrudan bir entegrasyon sunmaktadir. ```php // src/Security/ApiTokenHandler.php namespace App\Security; use App\Repository\ApiTokenRepository; use Symfony\Component\Security\Core\Exception\BadCredentialsException; use Symfony\Component\Security\Http\AccessToken\AccessTokenHandlerInterface; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; final readonly class ApiTokenHandler implements AccessTokenHandlerInterface { public function __construct( private ApiTokenRepository $repository, ) {} public function getUserBadgeFrom(#[\SensitiveParameter] string $accessToken): UserBadge { $token = $this->repository->findOneByValue($accessToken); if ($token === null || !$token->isValid()) { throw new BadCredentialsException('Invalid or expired token.'); } return new UserBadge($token->getUser()->getUserIdentifier()); } } ``` `AccessTokenHandlerInterface` arayuzu tek bir metod gerektirir: `getUserBadgeFrom`. Bu metod, istekten cikarilan ham tokeni alir (varsayilan olarak `Authorization: Bearer xxx` basligi) ve iliskili kullanicinin tanimlayicisini iceren bir `UserBadge` nesnesi dondurmelidir. `#[\SensitiveParameter]` ozelligi, tokeni hassas veri olarak isaretleyerek stack trace'lerde ve loglarda gorunmesini engeller — PHP 8.2'de tanilan bir guvenlik en iyi uygulamasi. Kalip kasitli olarak minimalisttir: token dogrulamasi (varlik, sure dolumu, iptal) repository veya ozel bir serviste kalir. Handler yalnizca bir tokeni kullanici kimligine donusturur. Bu sorumluluk ayrimi, birim testlerini kolaylastirir ve tek sorumluluk ilkesine uyar. ## Voter'lar: ayrintili erisim kontrolu Voter'lar, Symfony'de yetkilendirmenin merkezi mekanizmasini olusturur. `access_control` icerisinde tanimlanan statik rollerin aksine, voter'lar baglama dayali dinamik karar mantigi saglar: mevcut kullanici, hedef nesne ve istenen islem. Her voter, kesin bir soruyu yanitlar: "Bu kullanici, bu nesne uzerinde bu islemi gerceklestirebilir mi?" ```php // src/Security/Voter/PostVoter.php namespace App\Security\Voter; use App\Entity\Post; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\Voter\Vote; use Symfony\Component\Security\Core\Authorization\Voter\Voter; use Symfony\Component\Security\Core\User\UserInterface; final class PostVoter extends Voter { public const EDIT = 'POST_EDIT'; public const DELETE = 'POST_DELETE'; public const PUBLISH = 'POST_PUBLISH'; protected function supports(string $attribute, mixed $subject): bool { return in_array($attribute, [self::EDIT, self::DELETE, self::PUBLISH]) && $subject instanceof Post; } protected function voteOnAttribute( string $attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null, ): bool { $user = $token->getUser(); if (!$user instanceof UserInterface) { $vote?->addReason('User is not authenticated.'); return false; } /** @var Post $post */ $post = $subject; return match ($attribute) { self::EDIT => $this->canEdit($post, $user, $vote), self::DELETE => $this->canDelete($post, $user, $vote), self::PUBLISH => $this->canPublish($post, $user, $vote), default => false, }; } private function canEdit(Post $post, UserInterface $user, ?Vote $vote): bool { if ($post->getAuthor() === $user) { $vote?->addReason('User is the author of the post.'); return true; } $vote?->addReason('User is not the author.'); return false; } private function canDelete(Post $post, UserInterface $user, ?Vote $vote): bool { if (in_array('ROLE_ADMIN', $user->getRoles())) { $vote?->addReason('User has ROLE_ADMIN.'); return true; } if ($post->getAuthor() === $user && !$post->isPublished()) { $vote?->addReason('Author can delete unpublished posts.'); return true; } $vote?->addReason('Only admins or authors of unpublished posts can delete.'); return false; } private function canPublish(Post $post, UserInterface $user, ?Vote $vote): bool { if (in_array('ROLE_EDITOR', $user->getRoles())) { $vote?->addReason('User has ROLE_EDITOR.'); return true; } $vote?->addReason('Only editors can publish posts.'); return false; } } ``` Bu voter'in birkac ogesinin ayrintili incelemesi gerekmektedir. `Vote` parametresi (Symfony 7.1'de tanitildi), her karara metinsel gerekce eklenmesini saglar ve gelistirme ortaminda hata ayiklamayi, uretimde denetlenebilirligi kolaylastirir. `supports` metodu cagrilari filtreler: voter yalnizca `Post` ornegi ile iliskili `POST_EDIT`, `POST_DELETE` ve `POST_PUBLISH` ozellikleri icin etkinlesir. `voteOnAttribute` icindeki `match` ifadesi, mantigi her biri bir islemin is kurallarini kapsayan ozellestirilmis ozel metodlara devreder. Bu yapilandirma, voter'i okunabilir ve genisletilebilir kilar: yeni bir islem eklemek, bir sabit tanimlama, `match` icerisine bir durum ekleme ve bir ozel metod yazmakla sinirlidir. `canDelete` mantigi sik rastlanan bir kalip sergilemektedir: rol dogrulamasi ile sahiplik dogrulamasinin birlestirilmesi. Bir yonetici herhangi bir makaleyi silebilir, ancak bir yazar yalnizca kendi yayinlanmamis makalelerini silebilir. Bu tur baglamsal kurallar, `access_control` icindeki basit rollerle ifade edilemez. ## IsGranted ozelligi: bildirimsel erisim kontrolu `#[IsGranted]` ozelligi, erisim kontrolunu dogrudan denetleyici veya metod duzeyinde uygular ve eski guvenlik anotasyonlariyla ayni islevi yerel PHP sozdizimi ile yerine getirir. Symfony, ifadeyi metod yurutulmeden once degerlendirir ve dogrulama basarisiz olursa 403 yaniti dondurur. ```php // src/Controller/PostController.php namespace App\Controller; use App\Entity\Post; use App\Security\Voter\PostVoter; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; #[Route('/post')] final class PostController extends AbstractController { #[Route('/{id}/edit', methods: ['GET', 'POST'])] #[IsGranted(PostVoter::EDIT, subject: 'post', message: 'You cannot edit this post.')] public function edit(Post $post): Response { // User is guaranteed to have edit permission at this point return $this->render('post/edit.html.twig', [ 'post' => $post, ]); } #[Route('/{id}/publish', methods: ['POST'])] #[IsGranted(PostVoter::PUBLISH, subject: 'post')] public function publish(Post $post): Response { // Only editors reach this code $post->setPublished(true); // ... return $this->redirectToRoute('post_show', ['id' => $post->getId()]); } } ``` `subject: 'post'` parametresi, ozelligi ayni isimdeki metod parametresine baglar. Symfony, varlik cozumlemesini ParamConverter araciligiyla otomatik olarak yapar ve dogrulama konusu olarak voter'a iletir. `message` parametresi 403 hata mesajini ozellestirerek hem hata ayiklama hem de denetim loglari icin faydalidir. Bu bildirimsel yaklasiMin okunabilirlik acisindan onemli bir avantaji vardir: erisim kurallari, islevin govdesinin incelenmesine gerek kalmadan metod imzasiyla ayni yerde gorulur. Teknik mulakatlarda, ozellikten voter'a ve `AccessDecisionManager`'a uzanan tam yolu aciklayabilmek, Security bilesenine iliskin derin bir anlayis sergilemektedir. ## Karar stratejileri: unanimous, affirmative, consensus Birden fazla voter ayni erisim dogrulamasi hakkinda gorusunu bildirdiginde, `AccessDecisionManager` oylari toplamak icin bir karar stratejisi uygular. Symfony, `security.yaml` icerisinde yapilandirilabilir uc strateji sunar. ```yaml # config/packages/security.yaml security: access_decision_manager: strategy: unanimous allow_if_all_abstain: false ``` `affirmative` stratejisi (varsayilan), tek bir voter olumlu oy verdiginde erisim izni verir. `unanimous` stratejisi, cekinser olmayan tum voter'larin olumlu oy vermesini gerektirir. `consensus` stratejisi, voter'larin cogunlugu olumlu oy verdiginde erisim izni verir. `allow_if_all_abstain` parametresi, tum voter'lar cekinser kaldiginda (hicbiri istenen ozelligi desteklemediklerinde) davranisi belirler. Pratikte, varsayilan `affirmative` stratejisi cogu uygulama icin yeterlidir. `unanimous` stratejisi, guvenligin oncelikli oldugu baglamlarda dayatilir: finansal uygulamalar, tibbi veriler, kritik sistemler. Hicbir voter'in erisime itiraz etmedigini garanti ederek derinlemesine savunma katmani ekler. IP dogrulama voter'i, rol voter'i ve sahiplik voter'inin tumunun erisimi onaylamasi gerekir. ## Twig'de erisim karari hata ayiklama (Symfony 7.4) Symfony 7.4, erisim kararlarina iliskin gerekceri dogrudan Twig sablonlarinda sunarak guvenlik sistemi hata ayiklamasini zenginlestirmektedir. Voter'lara eklenen `Vote` parametresi burada tam anlamini bulmaktadir: `$vote->addReason()` ile bildirilen gerekceleri Profiler'da goruntulenir ve sablonlarda kosullu olarak gosterilebilir. ```twig {# templates/post/show.html.twig #} {% if is_granted('POST_EDIT', post) %} Edit {% endif %} {% if is_granted('POST_DELETE', post) %}
{% endif %} {% if app.debug %} {# Symfony 7.4: access decision debugging in Twig #} {% set decision = is_granted_debug('POST_EDIT', post) %}