Coder Social home page Coder Social logo

easy-security-bundle's Introduction


THIS BUNDLE IS NO LONGER MAINTAINED. SYMFONY 3.4 ADDED A SIMILAR FEATURE SO THIS IS NO LONGER NEEDED.


EasySecurityBundle

This bundle provides useful shortcuts to hide the Symfony Security component complexity.

Installation

Step 1: Download the Bundle

$ composer require easycorp/easy-security-bundle

This command requires you to have Composer installed globally, as explained in the Composer documentation.

Step 2: Enable the Bundle

<?php
// app/AppKernel.php

// ...
class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            // ...
            new EasyCorp\Bundle\EasySecurityBundle\EasySecurityBundle(),
        );
    }

    // ...
}

Basic Usage

Once installed, this bundle creates a new service called security that provides lots of shortcuts for the most common security operations. The main advantages over the Symfony Security component/bundle are:

1) It hides internal complexity

The Security component and bundle are some of the most complex Symfony pieces. They require you to learn lots of internal details that you probably don't care about:

// get the current user
$user = $this->get('security.token_storage')->getToken()->getUser();
// check their permissions
$user = $this->get('security.authorization_checker')->isGranted('ROLE_ADMIN');
// get the last login attempt error, if any
$error = $this->get('security.authentication_utils')->getLastAuthenticationError();

This bundle hides this complexity centralizing all the operations under the security service:

// get the current user
$user = $this->get('security')->getUser();
// check their permissions
$user = $this->get('security')->isGranted('ROLE_ADMIN');
// get the last login attempt error, if any
$error = $this->get('security')->getLoginError();

2) It makes code less verbose

Sometimes, the code needed to do common tasks is ridiculously verbose. For example, to login a user programmatically, Symfony requires you to do the following:

$user = ...
$token = new UsernamePasswordToken($user, $user->getPassword(), 'main', $user->getRoles());
$token->setAuthenticated(true);
$this->get('security.token_storage')->setToken($token);
$this->get('session')->set('_security_main', serialize($token));
$this->get('session')->save();

This bundle makes login a user as simple as it can be:

$user = ...
$this->get('security')->login($user);

3) It fixes some unintuitive behaviors

In Symfony applications, the way to check if a user is anonymous, remembered or fully authenticated doesn't work as most people expect. For example, if a user logs in with their username + password using a form login, this will happen:

// returns true
$this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_ANONYMOUSLY');
// returns true
$this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_REMEMBERED');
// returns true
$this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY');

Symfony grants the anonymous and remembered attributes to fully authenticated users, so it's complicated to differentiate between them. This bundle changes this unintuitive behavior and helps you know if a user is truly anonymous, remembered or authenticated. In the same example as before:

// returns false
$this->get('security')->isAnonymous();
// returns false
$this->get('security')->isRemembered();
// returns true
$this->get('security')->isFullyAuthenticated();

Injecting the security service

These shortcuts can be used across your application if you inject the security service. For example, if you define your services in YAML format:

# app/config/services.yml
services:
    app.my_service:
        # ...
        arguments: ['@security']

Then, update the constructor of your service to get the security service:

// src/AppBundle/MyService.php
// ...
use EasyCorp\Bundle\EasySecurityBundle\Security\Security;

class MyService
{
    private $security;

    public function __construct(Security $security)
    {
        $this->security = $security;
    }

    public function myMethod()
    {
        // ...
        $user = $this->security->getUser();
    }
}

List of Shortcuts

Getting users

  • getUser(): returns the current application user.
  • getImpersonatingUser(): when impersonating a user, it returns the original user who started the impersonation.

Checking permissions

  • isGranted($attributes, $object = null): checks if the attributes (usually security roles) are granted for the current application user and the optionally given object.
  • hasRole($role, $user = null): returns true if the current application user (or the optionally given user) has the given role. It takes into account the full role hierarchy.

Types of users

  • isAnonymous($user = null): returns true if the current application user (or the optionally given user) is anonymous. This behaves differently than Symfony built-in methods and it returns true only when the user is really anonymous.
  • isRemembered($user = null): returns true if the current application user (or the optionally given user) is remembered. This behaves differently than Symfony built-in methods and it returns true only when the user is really remembered and they haven't introduced their credentials (username and password).
  • isFullyAuthenticated($user = null): returns true if the current application user (or the optionally given user) is authenticated because they have introduced their credentials (username and password).
  • isAuthenticated($user = null): returns true if the current application user (or the optionally given user) is authenticated in any way (because they have introduced their credentials (username and password) or they have been remembered).

Login

  • login(UserInterface $user, $firewallName = 'main'): it logs in the given user in the main application firewall (or the optionally given firewall name).
  • getLoginError(): returns the error of the last failed login attempt, if any.
  • getLoginUsername(): returns the username of the last failed login attempt, if any.

Passwords

  • encodePassword($plainPassword, $user = null): returns the given plain password encoded/hashed using the encoder of the current application user or the optionally given user.
  • isPasswordValid($plainPassword, $user = null): returns true if the given plain password is valid for the current application user or the optionally given user.

easy-security-bundle's People

Contributors

javiereguiluz avatar kbond avatar ninsuo avatar phpdev avatar pierredup avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

easy-security-bundle's Issues

RoleHierarchy instance of Session

EasyCorp\Bundle\EasySecurityBundle\Security\Security::__construct() must be an instance of Symfony\Component\Security\Core\Role\RoleHierarchy, instance of Symfony\Component\HttpFoundation\Session\Session given

symfony": "^3.3

Proposal to add new helper methods

@ninsuo in this comment is proposing to add new methods:

<?php

namespace BaseBundle\Services;

use Doctrine\ORM\Proxy\Proxy;
use EasyCorp\Bundle\EasySecurityBundle\Security\Security as BaseSecurity;
use HWI\Bundle\OAuthBundle\Security\Core\Authentication\Token\OAuthToken;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\Security\Core\User\UserInterface;

class Security extends BaseSecurity
{
    use ContainerAwareTrait;

    /**
     * This method should only be used to enforce login on development
     * environment (when you don't have an internet connection for example)
     * or on demo websites where visitors can try features requiring authentication.
     *
     * @param int $id
     * 
     * @return Security
     */
    public function loginById($id)
    {
        $user = $this->container
           ->get('doctrine')
           ->getManager()
           ->getRepository('BaseBundle:User')
           ->findOneById($id);

        $this->login(
            $this->container
                ->get('base.oauth_user_provider')
                ->loadUserByUsername($user->getUsername())
        );

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function login(UserInterface $user, $firewallName = 'main')
    {
        $token = new OAuthToken(null, $user->getRoles());
        $token->setUser($this->getRealEntity($user));
        $token->setAuthenticated(true);
        $this->container->get('security.token_storage')->setToken($token);
        $this->container->get('session')->set("_security_{$firewallName}", serialize($token));
        $this->container->get('session')->save();

        return $this;
    }

    /**
     * This method is used to store a real entity and not a doctrine proxy
     * on the tokenstorage (they internally do a get_class and if the entity
     * was lazily loaded, it will be an instance of a proxy).
     *
     * @param mixed $proxy
     *
     * @return mixed
     */
    public function getRealEntity($proxy)
    {
        if ($proxy instanceof Proxy) {
            $metadata              = $this->getManager()->getMetadataFactory()->getMetadataFor(get_class($proxy));
            $class                 = $metadata->getName();
            $entity                = new $class();
            $reflectionSourceClass = new \ReflectionClass($proxy);
            $reflectionTargetClass = new \ReflectionClass($entity);
            foreach ($metadata->getFieldNames() as $fieldName) {
                $reflectionPropertySource = $reflectionSourceClass->getProperty($fieldName);
                $reflectionPropertySource->setAccessible(true);
                $reflectionPropertyTarget = $reflectionTargetClass->getProperty($fieldName);
                $reflectionPropertyTarget->setAccessible(true);
                $reflectionPropertyTarget->setValue($entity, $reflectionPropertySource->getValue($proxy));
            }

            return $entity;
        }

        return $proxy;
    }
}

He says that they are useful when:

On many dev purposes (notably when there are only hwi ways to login on disconnected envs), I required those.

Thoughts? Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.