Symfony中用户安全页面的最佳方法?

时间:2012-04-27 08:35:59

标签: php symfony1 symfony-1.4

我有数据库中的表格:

News:
id | user_id | title | body

和CRUD:

public function executeIndex(sfWebRequest $request)
public function executeNew(sfWebRequest $request)
public function executeShow(sfWebRequest $request)
public function executeCreate(sfWebRequest $request)
public function executeEdit(sfWebRequest $request)
public function executeUpdate(sfWebRequest $request)
public function executeDelete(sfWebRequest $request)
protected function processForm(sfWebRequest $request, sfForm $form)

如何确保安全的最佳方法? 我希望用户可以修改,更新删除仅拥有新闻。 我可以做到这一点 - 获取当前ID用户并与来自新闻和下一个重定向的user_id进行比较。也许我可以用preExecute或yaml文件制作这个?

2 个答案:

答案 0 :(得分:4)

我曾经做过这样的事情。

我选择使用方法myUser.class.php扩展User类(can($what, Doctrine_Record $with)在应用程序li​​b目录中),同样也声明了几种类型的更新类型,例如:const UPDATE = 'update';和其他类型的更新类型方式。

之后在preExecute()中我检索了当前请求的对象,在您的情况下 - 新闻对象,并调用if (!$this->getUser()->can(myUser::UPDATE, $news)) { /* redirect or whatever */ }

正如您所看到的,它非常易读且易于操作。

通过这种方式,您可以在一个方法中使用所有访问逻辑 - can(),您可以在其中指定所需的任何逻辑。

希望,这对你有所帮助。

对于您的示例,can()方法类似于:

switch(get_class($with))
{
    case 'News':
        if ($with->getUserId() != $this->getProfile()->getId()) // Assuming that getProfile() gives me a User class which News record is referenced
        {
            switch ($what)
            {
                case self::UPDATE:
                    return false;
                case self::DELETE:
                    return false;
            }
        }
        else
        {
            return true; // The user is owner - he can do whatever he want.
        }
        break;
    default:
        return false; // or true, don't know what you need
}

答案 1 :(得分:0)

我做了很多相同的事情。但我没有扩展sfUser类。我使用了symfony的过滤器链http://www.symfony-project.org/book/1_2/06-Inside-the-Controller-Layer#chapter_06_filters并编写了我自己的SecurityFilter,它能够解析路由配置。

我为routing.yml

的特定路线添加了一个选项
contact_list:
  url: /contacts/:usergroup
  param: { module: contacts, action: index }
    options: { securityManager: UsergroupListSecurityManager }

例如:securityFilter现在使用UsergroupListSecurityManager的实例来确定是否允许它显示页面。

所以我能够设置默认的“securityManager”并在特定路由上定义任何特定的“securityManagers” - 我还能够在不同的路由和其他上下文中重用一些“securityManager”(创建上下文菜单或工具栏)。 / p>