Skip to content

Instantly share code, notes, and snippets.

@umpirsky
Created May 31, 2011 11:33
Show Gist options
  • Save umpirsky/1000349 to your computer and use it in GitHub Desktop.
Save umpirsky/1000349 to your computer and use it in GitHub Desktop.
security.authentication.listener.url:
class: Мз\Security\Http\Firewall\UrlAuthenticationListener
arguments: [@security.context, @security.authentication.manager, @security.authentication.session_strategy, 'secured_area', {login_path: '/not-auth', check_path: '/auth/customer', default_target_path: '/хоме'}]
tags:
- { name: monolog.logger, channel: security }
security:
encoders:
Symfony\Component\Security\Core\User\User: plaintext
providers:
in_memory:
users:
admin: { password: admin, roles: 'ROLE_ADMIN' }
access_control:
- { path: ^/, roles: ROLE_ADMIN }
factories:
UrlSecurityFactory: %kernel.root_dir%/../src/My/Resources/config/security_factories.xml
firewalls:
profiler:
pattern: ^/_profiler
security: false
wdt:
pattern: ^/_wdt
security: false
notauth:
pattern: ^/not-auth
security: false
secured_area:
pattern: ^/
security: true
url_login: ~
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="security.authentication.factory.url" class="My\Security\Factory\UrlLoginFactory">
<tag name="security.listener.factory" />
</service>
</services>
</container>
<?php
namespace My\Security\Factory;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener;
use Symfony\Component\Security\Http\Firewall\AbstractAuthenticationListener;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\SecurityContextInterface;
class UrlAuthenticationListener extends AbstractAuthenticationListener
{
protected function attemptAuthentication(Request $request)
{
$username = 'admin';
$password = 'admin';
$request->getSession()->set(SecurityContextInterface::LAST_USERNAME, $username);
return $this->authenticationManager->authenticate(new UsernamePasswordToken($username, $password, $this->providerKey));
}
<?php
namespace My\Security\Factory;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface;
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AbstractFactory;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
/**
* UrlLoginFactory creates services for url login authentication.
*
* @author umpirsky
*/
class UrlLoginFactory extends AbstractFactory
{
/**
* @see Symfony\Bundle\FrameworkBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface::getPosition()
*/
public function getPosition()
{
return 'pre_auth';
}
/**
* @see Symfony\Bundle\FrameworkBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface::getKey()
*/
public function getKey()
{
return 'url-login';
}
protected function getListenerId()
{
return 'security.authentication.listener.url';
}
protected function createAuthProvider(ContainerBuilder $container, $id, $config, $userProviderId)
{
$provider = 'security.authentication.provider.dao.'.$id;
$container
->setDefinition($provider, new DefinitionDecorator('security.authentication.provider.dao'))
->replaceArgument(0, new Reference($userProviderId))
->replaceArgument(2, 'secured_area')
->addArgument($id)
;
return $provider;
}
protected function createListener($container, $id, $config, $userProvider)
{
$listenerId = $this->getListenerId();
$listener = new DefinitionDecorator($listenerId);
$listenerId .= '.'.$id;
$container->setDefinition($listenerId, $listener);
return $listenerId;
}
protected function createEntryPoint($container, $id, $config, $defaultEntryPointId)
{
return $defaultEntryPointId;
}
}
@umpirsky
Copy link
Author

For now they are hardcoded in https://gist.github.com/1000349#file_url_authentication_listener.php. But they will be passed like /auth/username/admin/hash/foo via url. But I'm hardcoding for now to keep it simpler for testing. Passing user/pass is not the problem I'm trying to solve now. Problem is authentication itself.

With current listener implementation https://gist.github.com/1000349#file_url_authentication_listener.php with 'admin' username it is always authenticated, no matter what password (credentials) I enter. And it triggers authentication on all urls, but I guess that's how AbstractPreAuthenticatedListener works.

@umpirsky
Copy link
Author

If we ever solve this, I will write detailed instructions about implementing custom authentication system with Symfony2.

@umpirsky
Copy link
Author

umpirsky commented Jun 1, 2011

OK, I kind of sorted it all out. I switched to AbstractAuthenticationListener instead AbstractPreAuthenticatedListener. Added provider key and config to https://gist.github.com/1000349#file_cnofig.yml. And add some magic in createAuthProvider() method. Now it works.

The only thing that are not clear to me are is what is providerKey? I hardcoded it in createAuthProvider() and config.yml, but don't know what is it and how to use it?

Thanks.

@umpirsky
Copy link
Author

umpirsky commented Jun 1, 2011

Strange is that I don't get usual "Full authenticvation required to access this resource" when I'm unauthorised and go to some protected url, but get "A Token was not found in the SecurityContext.".

@kayue
Copy link

kayue commented Aug 7, 2011

Hi umpirsky, did you figure out how to solve this?

@umpirsky
Copy link
Author

@kayue Yes, but it was very hard work, and I suggest you to give up, you can make it on your own better. Maybe situation is now better since stable Symfony2 is released.

@kayue
Copy link

kayue commented Aug 16, 2011

@umpirsky:

I was trying to create a Wordpress Bridge (https://github.com/kayue/WordpressBundle).
I figured out the "A Token was not found in the SecurityContext." could be fixed if I add anonymous to my firewall.

Don't know are we talking about the same issue.

@umpirsky
Copy link
Author

@kayue I think not :)

@ecoad
Copy link

ecoad commented Nov 16, 2011

@kayue:

Thankyou! Add "anonymous" to firewall

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment