Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/236.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Symfony 2-重定向后身份验证令牌丢失_Php_Authentication_Symfony - Fatal编程技术网

Php Symfony 2-重定向后身份验证令牌丢失

Php Symfony 2-重定向后身份验证令牌丢失,php,authentication,symfony,Php,Authentication,Symfony,我对symfony2有问题(我在Symfony 2.0和Symfony 2.3上也尝试了同样的方法,只是为了看看这是否是一个Symfony bug),我在身份验证后的下一页加载/重定向中丢失了安全令牌 我已为Symfony 2.3创建了自定义身份验证程序,以使用此处指定的第三方服务进行身份验证: 应用程序使用外部服务进行身份验证,并在回调URL“/success”中设置令牌,我可以从调试栏看到用户已通过身份验证,但当我转到“/”(位于同一防火墙下)时,我得到“SecurityContext中未找

我对symfony2有问题(我在Symfony 2.0和Symfony 2.3上也尝试了同样的方法,只是为了看看这是否是一个Symfony bug),我在身份验证后的下一页加载/重定向中丢失了安全令牌

我已为Symfony 2.3创建了自定义身份验证程序,以使用此处指定的第三方服务进行身份验证:

应用程序使用外部服务进行身份验证,并在回调URL“/success”中设置令牌,我可以从调试栏看到用户已通过身份验证,但当我转到“/”(位于同一防火墙下)时,我得到“SecurityContext中未找到令牌”。错误,用户不再经过身份验证

以下是文件:

security.yml

NoaUserToken.php


您应该在请求对象上使用会话接口,而不是在NoaListener中使用会话。Symfony自行进行会话管理,可能会忽略或覆盖您的会话(例如,成功登录后迁移会话以防止会话固定攻击是很常见的)


使用您已有的
$request=$event->getRequest()
,然后使用
$request->getsession()->get('userInfo')
,等等。

非常感谢inanimatt注意到,实际上第三方库正在重置会话,我必须重写第三方库中的会话处理来修复此问题。
security:
    encoders:
        Symfony\Component\Security\Core\User\User: plaintext

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

    providers:
        users:
            entity: { class: AcmeStoreBundle:User, property: email }

    firewalls:
        login:
            pattern:  ^/login$
            security: false
        noa:
            pattern:  ^/
            provider: users
            noa: true
            logout:
                path:   /logout
                target: /login

    access_control:
        - { path: ^/success, roles: IS_AUTHENTICATED_ANONYMOUSLY }
<?php
namespace Acme\StoreBundle\Security\Authentication\Token;

use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;

class NoaUserToken extends AbstractToken
{
    public $expires;
    public $mobile;
    public $email;

    public function __construct(array $roles = array())
    {
        parent::__construct($roles);

        parent::setAuthenticated(true);
    }

    public function getCredentials()
    {
        return '';
    }
}
<?php
namespace Acme\StoreBundle\Security\Authentication\Provider;

use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\NonceExpiredException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Acme\StoreBundle\Security\Authentication\Token\NoaUserToken;

class NoaProvider implements AuthenticationProviderInterface
{
    private $userProvider;
    private $cacheDir;

    public function __construct(UserProviderInterface $userProvider, $cacheDir)
    {
        $this->userProvider = $userProvider;
        $this->cacheDir     = $cacheDir;
    }

    public function authenticate(TokenInterface $token)
    {
        $userEmail = $token->getUser();

        $user = $this->userProvider->loadUserByUsername($userEmail);

        if ($user && $this->validateToken($token->expires) && !$user->getHidden()) {
            $authenticatedToken = new NoaUserToken($user->getRoles());
            $authenticatedToken->expires = $token->expires;
            $authenticatedToken->mobile = $token->mobile;
            $authenticatedToken->email = $token->email;
            $authenticatedToken->setUser($user);
            $authenticatedToken->setAuthenticated(true);

            return $authenticatedToken;
        }

        throw new AuthenticationException('The NOA authentication failed.');
    }

    protected function validateToken($expires)
    {
        // Check if the token has expired.
        if (strtotime($expires) <= time()) {
            return false;
        }
    }

    public function supports(TokenInterface $token)
    {
        return $token instanceof NoaUserToken;
    }
}
<?php
namespace Acme\StoreBundle\Security\Firewall;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
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;
use Acme\StoreBundle\Security\Authentication\Token\NoaUserToken;

class NoaListener 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();

        if (! preg_match('/^\/app_dev.php\/success/', $request->getRequestUri())) {
            return;
        }

        if( $this->securityContext->getToken() ){
            return;
        }

        try {
            \NOA_Sso_Web::getInstance()->createSession();
        } 
        catch (Exception $e) {
            // Handle error situation here
        }

        if (isset($_SESSION['userInfo'])) {
            $token = new NoaUserToken();
            $token->setUser($_SESSION['userInfo']['email']);

            $token->mobile   = $_SESSION['userInfo']['mobileVerified'] ? $_SESSION['userInfo']['mobile'] : null;
            $token->email    = $_SESSION['userInfo']['emailVerified'] ? $_SESSION['userInfo']['email'] : null;
            $token->expires  = $_SESSION['tokenInfo']['expires'];

            try {
                $authToken = $this->authenticationManager->authenticate($token);
                $this->securityContext->setToken($authToken);
                return;
            } catch (AuthenticationException $failed) {
                // Do nothing and go for the default 403
            }
        }

        $this->securityContext->setToken(null);

        // Deny authentication with a '403 Forbidden' HTTP response
        $response = new Response();
        $response->setStatusCode(403);
        $event->setResponse($response);
    }
}
<?php
namespace Acme\StoreBundle\DependencyInjection\Security\Factory;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface;

class NoaFactory implements SecurityFactoryInterface
{
    public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint)
    {
        $providerId = 'security.authentication.provider.noa.'.$id;
        $container
            ->setDefinition($providerId, new DefinitionDecorator('noa.security.authentication.provider'))
            ->replaceArgument(0, new Reference($userProvider))
        ;

        $listenerId = 'security.authentication.listener.noa.'.$id;
        $listener = $container->setDefinition($listenerId, new DefinitionDecorator('noa.security.authentication.listener'));

        return array($providerId, $listenerId, $defaultEntryPoint);
    }

    public function getPosition()
    {
        return 'pre_auth';
    }

    public function getKey()
    {
        return 'noa';
    }

    public function addConfiguration(NodeDefinition $node)
    {
    }
}
<?php

namespace Acme\StoreBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\HttpFoundation\Response;

class DefaultController extends Controller
{
    public function indexAction()
    {
        $token = $this->container->get('security.context')->getToken();

        // Not reached
        print '<pre>';
        print_r($token->getUser());
        print '</pre>';
        return $this->render('AcmeStoreBundle:Default:index.html.twig', array('name' => $token->getUser()->gerUsername()));
    }
    public function loginAction()
    {
        return $this->render('AcmeStoreBundle:Default:login.html.twig', array());
    }
    public function successAction()
    {
        $token = $this->container->get('security.context')->getToken();
        $this->container->get('event_dispatcher')->dispatch(
            SecurityEvents::INTERACTIVE_LOGIN,
            new InteractiveLoginEvent($this->container->get('request'), $token)
        );

        // This prints the user object
        print '<pre>';
        print_r($token->getUser());
        print '</pre>';
        return new Response('<script>//window.top.refreshPage();</script>');
    }
}