28K Views

Symfony Security Voters

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

Authentication : Authentication is processed 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 process decides whether or not the current user can access some URI, or modify a certain object. There are 2 ways (ACL and Voters), but Voters is an easier solution to perform these restrictions.

Symfony Voter is a mechanism to provide access to the current user for some resources. The voter is a class that contains 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 the isGranted method, you can also pass an object to the isGranted method as a second argument and that argument will pass to the voter.

Let’s 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 calls the isGranted method and if the user is not authorized then it creates an access denied exception (403 forbidden).

Create a ticket voter where we have to write our logic to restrict the 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 the isGranted method, we return true if the 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.

Category(s) UVdesk
. . .

Comment

Add Your Comment

Be the first to comment.

css.php