Skip to content

Instantly share code, notes, and snippets.

@peterjwest
Last active August 29, 2015 13:59
Show Gist options
  • Save peterjwest/10978305 to your computer and use it in GitHub Desktop.
Save peterjwest/10978305 to your computer and use it in GitHub Desktop.
Intercepting a request Rails, express.js and Symfony2

How to intercept any request that matches a route (in this case '/admin') in three different languages/frameworks.

class AdminController < ApplicationController
before_action :check_request
def check_request
# ADD CODE HERE
end
end
# - routes.rb
# namespace :admin do
# ...
# end
var check_request = function(req, res, next) {
// ADD CODE HERE
};
app.use('/admin', check_request);
<?php
namespace Project\Bundle\Security\Authentication\Token;
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
class Token extends AbstractToken
{
public function getCredentials()
{
return "";
}
}
namespace Project\Bundle\DependencyInjection\Security\Factory;
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface;
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Reference;
class Factory implements SecurityFactoryInterface
{
public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint)
{
$provider = 'project.security.request_auth_provider.' . $id;
$container->setDefinition($provider, new DefinitionDecorator('project.security.request_auth_provider'));
$entryPointId = $this->createEntryPoint($container, $id, $config, $defaultEntryPoint);
$listenerId = 'project.security.authentication.request_listener.' . $id;
$listener = $container->setDefinition($listenerId, new DefinitionDecorator('project.security.authentication.request_listener'));
$listener->replaceArgument(1, new Reference($entryPointId));
return array($provider, $listenerId, $entryPointId);
}
public function getPosition()
{
return "pre_auth";
}
public function getKey()
{
return "check_request";
}
public function addConfiguration(NodeDefinition $builder)
{
}
protected function getListenerId()
{
return "project.security.authentication.request_listener";
}
protected function createEntryPoint($container, $id, $config, $defaultEntryPointId)
{
$entryPointId = 'project.security.request_entry_point.'.$id;
$container
->setDefinition($entryPointId, new DefinitionDecorator('project.security.request_entry_point'))
->addArgument(new Reference("service_container"))
;
return $entryPointId;
}
}
namespace Project\Bundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Project\Bundle\DependencyInjection\Compiler\SecurityLoggerPass;
class ProjectBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$extension = $container->getExtension("security");
$extension->addSecurityListenerFactory(new DependencyInjection\Security\Factory\Factory());
$container->addCompilerPass(new SecurityLoggerPass());
}
}
namespace Project\Bundle\Security\Authentication\Provider;
use Project\Bundle\Security\Authentication\Token\Token;
use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
class AuthProvider implements AuthenticationProviderInterface
{
public function authenticate(TokenInterface $token)
{
if (!$this->supports($token)) {
return null;
}
throw new \Exception("Server configuration error");
}
public function supports(TokenInterface $token)
{
return $token instanceof Token;
}
}
namespace Project\Bundle\Security\Authentication\Listener;
use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
use Symfony\Component\Security\Http\Firewall\ListenerInterface;
class RequestListener implements ListenerInterface
{
protected $securityContext;
protected $authenticationEntryPoint;
protected $em;
protected $enabled;
public function __construct(SecurityContextInterface $securityContext, AuthenticationEntryPointInterface $authenticationEntryPoint, EntityManager $em)
{
$this->securityContext = $securityContext;
$this->authenticationEntryPoint = $authenticationEntryPoint;
$this->em = $em;
}
public function handle(GetResponseEvent $event)
{
// ADD CODE HERE
}
}
/*
- services.yml
services:
project.security.authentication.request_listener:
class: Project\Bundle\Security\Authentication\Listener\RequestListener
arguments: [@security.context, null, @doctrine.orm.entity_manager]
project.security.request_auth_provider:
class: Project\Bundle\Security\Authentication\Provider\AuthProvider
public: false
- security.yml
security:
firewalls:
admin:
pattern: ^/admin
check_request: ~
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment