-
-
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; | |
} | |
} |
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.
If we ever solve this, I will write detailed instructions about implementing custom authentication system with Symfony2.
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.
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.".
Hi umpirsky, did you figure out how to solve this?
@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.
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.
@kayue I think not :)
Thankyou! Add "anonymous" to firewall
How are the username and password passed to the app ? can you give an example of url ?