2015-07-02 111 views
0

我在HHVM上使用Silex框架,並在嘗試實施登錄時執行SecurityServiceProvider時遇到一些問題。Silex SecurityServiceProvider嘗試進行身份驗證時在HHVM上存儲AnonymousToken

當試圖執行登錄操作(使用正確的用戶名&密碼)時,我被重定向到登錄頁面而不是/頁面。這是因爲以下訪問規則:

$app['security.access_rules'] = array(
    array('^/$', 'ROLE_USER') 
); 

我試着在登錄頁面的頂部傾銷$app['security.token_storage']->getToken()$app['security.token_storage']->getToken()->getUser()

object(Symfony\Component\Security\Core\Authentication\Token\AnonymousToken)#350 (5) { 
    ["key":"Symfony\Component\Security\Core\Authentication\Token\AnonymousToken":private]=> string(3) "all" 
    ["user":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=> string(5) "anon." 
    ["roles":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=> array(0) { } 
    ["authenticated":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=> bool(true) 
    ["attributes":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=> array(0) { } } 

的用戶名顯示爲anon.這不是我的用戶名(test)。

通過哈克調試,我可以確認:正在創建

  1. 用戶對象。
  2. 密碼正在驗證中,並且返回true。

    控制器路線:

    public function login(Application $app) 
        { 
        $form = $app['form.factory']->createBuilder('form') 
               ->add('username', 'text',  array('label' => 'Username')) 
               ->add('password', 'password', array('label' => 'Password')) 
               ->getForm(); 
    
        return $app['twig']->render('user/login.tpl', array(
         'title' => "Login", 
         'form' => $form->createView(), 
         'error' => $app['security.last_error']($app['request']) 
        )); 
        } 
    

    登錄模板 - 應用程序代碼的

相關部分(它大致基於@mpm's Silex MVC如果他的登錄代碼產生更好的效果尚未證實) :

{% block content %} 
    <h1>Login</h1> 

    {% if error %} 
    <div> 
     {{ error }} 
    </div> 
    {% endif %} 

    <form action="{{ path('user_login_check') }}" method="post" novalidate {{ form_enctype(form) }} class="form-vertical"> 
    {{ form_widget(form) }} 
    <button type="submit">Login</button> 
    </form> 
{% endblock %} 

安全相關服務聲明:

$app->register(new SecurityServiceProvider(), array(
    "security.firewalls" => array(
    // All other URLs require authentication. 
    "all" => array(
     "pattern" => '^/.*$', 
     "form" => array(
     "login_path"   => '/user/login', 
     "check_path"   => '/user/login_check', 
     "default_target_path" => '/', 
     "username_parameter" => 'form[username]', 
     "password_parameter" => 'form[password]' 
    ), 
     "anonymous" => true, 
     "logout" => array(
     "logout_path" => "/user/logout" 
    ), 
     "users" => $app->share(function() use ($app) { 
     return new UserProvider($app['db']); 
     }) 
    ) 
) 
)); 

$app['security.encoder.digest'] = $app->share(function ($app) { 
    return new PasswordEncoder($app['config']['security']['bcrypt_cost']); 
}); 

$app['security.role_hierarchy'] = array(
    "ROLE_ADMIN" => array(
    "ROLE_USER", 
    "ROLE_CREATE_CHARACTER", 
    "ROLE_CREATE_ORIGIN", 
    "ROLE_CREATE_COMMISSION", 
    "ROLE_DELETE_CHARACTER", 
    "ROLE_DELETE_ORIGIN", 
    "ROLE_DELETE_COMMISSION" 
), 
    "ROLE_ARTIST" => array(
    "ROLE_USER", 
    "ROLE_CREATE_COMMISSION" 
), 
    "ROLE_WRITER" => array(
    "ROLE_USER", 
    "RULE_CREATE_ORIGIN" 
) 
); 

$app['security.access_rules'] = array(
    array('^/$', 'ROLE_ADMIN') 
); 

我的用戶等級:

<?php 

namespace Coco\Model; 

use Symfony\Component\Security\Core\User\UserInterface; 
use Symfony\Component\Security\Core\User\EquatableInterface; 

class User implements UserInterface, EquatableInterface 
{ 
    private $username; 
    private $password; 
    private $roles; 

    public function __construct($username, $password, array $roles) 
    { 
    $this->username = $username; 
    $this->password = $password; 
    $this->roles = $roles; 
    } 

    public function getUsername() 
    { 
    return $this->username; 
    } 

    public function getPassword() 
    { 
    return $this->password; 
    } 

    public function getRoles() 
    { 
    return $this->roles; 
    } 

    public function eraseCredentials() 
    { 

    } 

    public function getSalt() 
    { 
    return null; 
    } 

    public function isEqualTo(UserInterface $user) 
    { 
    if (false === $user instanceof User) { 
     return false; 
    } elseif ($this->password !== $user->getPassword()) { 
     return false; 
    } elseif ($this->username !== $user->getUsername()) { 
     return false; 
    } else { 
     return true; 
    } 
    } 
} 

我UserProvider類:

<?php 

namespace Coco\Provider; 

use Coco\Exception\UnsupportedUserException; 
use Coco\Exception\UsernameNotFoundException; 
use Coco\Provider; 
use Coco\Model\User; 
use Symfony\Component\Security\Core\User\UserProviderInterface; 
use Symfony\Component\Security\Core\User\UserInterface; 

class UserProvider extends Provider implements UserProviderInterface 
{ 
    public function loadUserByUsername($username) 
    { 
    $username = strtolower($username); 

    $query = "SELECT `username`, `password`, `roles` FROM `user` WHERE `status` = 'active' AND `username` = ?"; 
    $stmt = $this->db->executeQuery($query, array($username)); 
    $user = $stmt->fetch(); 

    if (false === $user) { 
     throw new UsernameNotFoundException(sprintf('User "%s" not found.', $username)); 
    } 

    return new User(
     $user['username'], 
     $user['password'], 
     explode(',', $user['roles']) 
    ); 
    } 

    public function refreshUser(UserInterface $user) 
    { 
    if (false === $user instanceof User) { 
     throw new UnsupportedUserException(sprintf('Instance of "%s" not supported.', get_class($user))); 
    } 

    return $this->loadUserByUsername($user->getUsername()); 
    } 

    public function supportsClass($class) 
    { 
    return $class === 'Coco\Model\User'; 
    } 
} 

我有一個SessionServiceProviderFormServiceProvider運行。

我不知道如何正確調試這個問題,因爲缺乏熟悉的框架。如果任何人都可以指出我正確的方向,將不勝感激。

+0

首先,你應該啓用[monolog服務提供者](http://silex.sensiolabs.org/doc/providers/monolog.html),當啓用日誌功能時,安全組件爲你提供大量信息,從這裏開始並回發您的記錄認證嘗試。 – mTorres

+0

@mTorres - 我已經擁有monolog日誌記錄信息了。我認爲這是一個HHVM問題,因爲它運行在PHP上。搜索解決方法。 –

回答

1

因此,經過一番搜索,我發現this GitHub issue report,這證實這是一個偏離PHP5標準行爲的HHVM/Symfony會話問題。

切換到PdoSessionHandler對我來說是一個可行的解決方法,但不適用於所有情況,所以儘管我將此答案標記爲「正確」,但它可能不適用於所有人。

+0

非常漂亮! – mTorres

相關問題