Skip to content

Instantly share code, notes, and snippets.

@fesor
Last active December 28, 2015 20:49
Show Gist options
  • Save fesor/7559733 to your computer and use it in GitHub Desktop.
Save fesor/7559733 to your computer and use it in GitHub Desktop.
REST auth for symfony2
<?php
namespace App\ApiBundle\Security\Authentication;
use App\CoreBundle\Entity\User;
use App\ApiBundle\Security\ApiToken;
use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
class ApiAuthenticationProvider implements AuthenticationProviderInterface
{
private $userProvider;
public function __construct(UserProviderInterface $userProvider)
{
$this->userProvider = $userProvider;
}
public function authenticate(TokenInterface $token)
{
$user = $this->userProvider->findByToken($token->getApiToken());
if ($user && $user->getToken() !== '' && !$user->getRemoved())
{
$authenticatedToken = new ApiToken($user->getRoles());
$authenticatedToken->setUser($user);
return $authenticatedToken;
}
throw new AuthenticationException('The HTTP authentication failed.');
}
public function supports(TokenInterface $token)
{
return $token instanceof ApiToken;
}
}
<?php
namespace MyMob\ApiBundle\Security\Firewall;
use App\ApiBundle\Security\ApiToken;
use Symfony\Component\Form\Exception\Exception;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Security\Http\Firewall\ListenerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
class ApiListener implements ListenerInterface
{
protected $securityContext;
protected $authenticationManager;
public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager)
{
$this->securityContext = $securityContext;
$this->authenticationManager = $authenticationManager;
}
public function handle(GetResponseEvent $event)
{
$request = $event->getRequest();
$token = new ApiToken();
if ($request->headers->has('Token') && $request->headers->get('Token') !== '') {
$token->setApiToken($request->headers->get('Token'));
}
try {
$authToken = $this->authenticationManager->authenticate($token);
$this->securityContext->setToken($authToken);
} catch (AuthenticationException $failed) {
// Deny authentication with a '403 Forbidden' HTTP response
$response = new Response();
$response->setStatusCode(403);
$event->setResponse($response);
}
}
}
<?php
namespace App\ApiBundle\Security\Factory;
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
class ApiSecurityFactory implements SecurityFactoryInterface
{
public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint)
{
$providerId = 'security.authentication.provider.api.'.$id;
$container
->setDefinition($providerId, new DefinitionDecorator('api.security.authentication.provider'))
->replaceArgument(0, new Reference($userProvider))
;
$listenerId = 'security.authentication.listener.api.'.$id;
$listener = $container->setDefinition($listenerId, new DefinitionDecorator('api.security.authentication.listener'));
return array($providerId, $listenerId, $defaultEntryPoint);
}
public function getPosition()
{
return 'pre_auth';
}
public function getKey()
{
return 'api';
}
public function addConfiguration(NodeDefinition $node)
{
}
}
<?php
namespace App\ApiBundle\Security;
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
use Symfony\Component\Security\Core\User\UserInterface;
class ApiToken extends AbstractToken
{
protected $apiToken;
protected $roles;
public function setApiToken($apiToken)
{
$this->apiToken = $apiToken;
}
public function getApiToken()
{
return $this->apiToken;
}
public function getCredentials()
{
}
}
providers:
api:
id: api.user_manager
firewalls:
login_firewall:
pattern: ^/api/secure/login$
anonymous: ~
register_firewall:
pattern: ^/api/secure/register$
anonymous: ~
reset_password_firewall:
pattern: ^/api/secure/reset_password$
anonymous: ~
api_secured:
pattern: ^/api/.*
api: true
provider: api
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment