Symfony Security Voters

In web application security is a serious concern, if your application is not enough secure that can create a serious problems. So how we can assure our application is secured ? There are 2 security design Authentication and Authorization.

Authentication : Authentication is process when you use your credentials (eg. username and password) to login to the system.

Authorization : After the authentication process, application knows who you are. But can you access certain resources of the application or not is authorization.

Symfony authorization proccesss decide whether or not the current user can access some URI, or modify certain object. There are 2 ways (ACL and Voters), but Voters is an easier solution to perform these restriction.

Symfony Voters is a mechanism to provide access to the current user for some resources. Voter is a class that contain isGranted method where we write our complex business logic that decides you have permission or not to access this URI , or object.

All voters called each time whenever you called isGranted method, you can also pass an object to isGranted method as a second argument and that argument will pass to the voter.

Lets create a scenario for the better understanding of voters, suppose there is a ticket with id #1000 which is assigned to Agent A and Agent B is trying to access this ticket but Agent B has no permission to access this ticket.

So create a voter to overcome this situation.

/**
* Webkul Software.
*
* @category Webkul
* @package Webkul_Uvdesk
* @author Webkul
* @copyright Copyright (c) 2010-2016 Webkul Software Private Limited (https://webkul.com)
* @license https://store.webkul.com/license.html
*/
// Webkul/UvdeskBundle/Controller/TicketController;
class TicketController extends Controller
{
public function viewAction(Request $request)
{
// ...
       $ticket = $this->getDoctrine()->getRepository('UvdeskBundle:Ticket')->find($id);
       $this->denyAccessUnlessGranted('VIEW_TICKET',  $ticket);
       // ...
}
}

In the above controller, we check if the current user can access this ticket by calling the denyAccessUnlessGranted method of symfony core Controller from Symfony\Bundle\FrameworkBundle\Controller namespace. Method denyAccessUnlessGranted is a simpler isGranted method that call isGranted method and if user is not authorized than it creates a access denied exception (403 forbidden).

Create a ticket voter where we have write our logic to restrict user to access the ticket.

/**
* Webkul Software.
*
* @category Webkul
* @package Webkul_Uvdesk
* @author Webkul
* @copyright Copyright (c) 2010-2016 Webkul Software Private Limited (https://webkul.com)
* @license https://store.webkul.com/license.html
*/
// Webkul/UvdeskBundle/Security/TicketVoter;
class TicketVoter extends AbstractVoter
{
    private $attributesArray = array('VIEW_TICKET', 'DELETE_TICKET');
    protected function supports($attribute, $subject)
{
// check if attribute is supportive
if (!in_array($attribute, $attributesArray) {
return false;
}
        // Vote on Ticket object
if (!$subject instanceof Ticket) {
return false;
}
        return true;
}
    protected function getSupportedClasses()
{
return array('Webkul\UvdeskBundle\Entity\Ticket');
}
    protected function getSupportedAttributes()
{
return $this->attributesArray;
}
    protected function isGranted($attribute, $ticket, $user = null) { 
$user = $token->getUser();
if (!$user instanceof User) {
return false;
}
       switch ($attribute) { 
case 'VIEW_TICKET':
if($user->getRole() == 'ROLE_ADMIN' || $user == $ticket->getAgent())
return true;
return false;
case 'DELETE_TICKET':
if($user->getRole() == 'ROLE_ADMIN')
return true;
return false;
}
}
}

In isGranted method, we return true if current user has access and false if not.

For making this voter work, you need to configure this voter in your service.yml file. Below is the code for configuration of voter:

# Resources/config/services.yml
services:
uvdesk.ticket_voter:
class: Uvdesk\Security\TicketVoter
tags:
- { name: security.voter }

That’s it. You can write your own business logic based on your need.

You can also check Symfony Voters on symfony documentation http://symfony.com/doc/current/security/voters.html

Thanks for your time.

Like what you read? Give Jitendra Singh a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.