草庐IT

php - Symfony 2 ACL 和角色层次结构

coder 2024-04-15 原文

我有点卡住了,找不到这个问题的答案。

在我的应用测试中,我创建了两个实体 User 和 Comment,它们都已正确映射。

我创建了一个小型 Controller ,如果我将评论和数据添加到 ACL 表,如果我将评论创建为标准用户并关联“ROLE_USER” ,并尝试以角色“ROLE_ADMIN”的用户身份访问它我被拒绝访问,它似乎完全忽略了 security.yml 层次结构。

我知道这可以通过添加 ROLE_USER 等而不是用户 ID 来实现,但我不想这样做。

我的代码示例如下。

评论 Controller

    <?php

    namespace ACL\TestBundle\Controller;

    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
    use Symfony\Component\HttpFoundation\Request;
    use ACL\TestBundle\Forms\Type\commentType;
    use ACL\TestBundle\Entity\Comment;
    use Symfony\Component\Security\Core\Exception\AccessDeniedException;
    use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
    use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
    use Symfony\Component\Security\Acl\Permission\MaskBuilder;

    class DefaultController extends Controller
    {
        /**
         * @Route("/", name="_default")
         * @Template()
         */
        public function indexAction()
        {
            die('success');
        }

        /**
         * @Route("/comment/new/")
         * @Template()
         */
        public function newAction(Request $request)
        {
            $comment = new Comment();

            $form = $this->createForm(new commentType(), $comment);

            $form->handleRequest($request);

            if ($form->isValid()) {
                $comment->setUsers($this->getUser());
                $em = $this->getDoctrine()->getManager();
                $em->persist($comment);
                $em->flush();

                // creating the ACL
                $aclProvider = $this->get('security.acl.provider');
                $objectIdentity = ObjectIdentity::fromDomainObject($comment);
                $acl = $aclProvider->createAcl($objectIdentity);

                // retrieving the security identity of the currently logged-in user
                $securityIdentity = UserSecurityIdentity::fromAccount($this->getUser());

                // grant owner access
                $acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_OWNER);
                $aclProvider->updateAcl($acl);
            }

            return array(
                'form' => $form->createView(),
            );
        }

        /**
         * @Route("/comment/{id}/", requirements={"id":"\d+"})
         * @Template()
         */
        public function editAction(Request $request,$id)
        {
            $em = $this->getDoctrine()->getManager();
            $comment = $em->find('ACLTestBundle:Comment', $id);

            $securityContext = $this->get('security.context');

            // check for edit access
            if (false === $securityContext->isGranted('EDIT',$comment)) {
                throw new AccessDeniedException();
            }

            $form = $this->createForm(new commentType(), $comment);

            $form->handleRequest($request);

            if($form->isValid()){
                $em->persist($comment);
                $em->flush();
            }

            return array('form' => $form->createView());
        }
    }

安全.yml

 security:
        encoders:
            ACL\TestBundle\Entity\User: plaintext
        acl:
            connection: default

        providers:
            database:
                entity: { class: ACLTestBundle:User }

        role_hierarchy:
            ROLE_ADMIN: [ROLE_USER, ROLE_ALLOWED_TO_SWITCH]

        firewalls:
            dev:
                pattern:  ^/(_(profiler|wdt)|css|images|js)/
                security: false
            main:
                pattern:     ^/
                provider:    database
                anonymous:   true
                logout:      true
                switch_user: true
                form_login:
                    login_path: _security_login

        access_control:
            - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
            - { path: ^/, roles: IS_AUTHENTICATED_FULLY }

我很感激任何建议!

最佳答案

问题是您正在添加基于 UserIdentity 的 ACL,并希望检查基于 RoleIdentity 的 gran。如果你想这样做 Role base 如下更改创建的 ACL

// creating the ACL
$aclProvider = $this->get('security.acl.provider');
$objectIdentity = ObjectIdentity::fromDomainObject($comment);
$acl = $aclProvider->createAcl($objectIdentity);

// retrieving the security identity of the currently logged-in user
$securityIdentity = UserSecurityIdentity::fromAccount($this->getUser());

// grant owner access
$acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_OWNER);

// grant EDIT access to ROLE_ADMIN
$securityIdentity = new RoleSecurityIdentity('ROLE_ADMIN');
$acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_EDIT);
$aclProvider->updateAcl($acl);

如您所见,我保留了特定用户的所有者访问权限,然后我为 ROLE_ADMIN 添加了编辑访问权限。您可以保持 Controller 不变。

如果你不想让它成为角色基础,而只是想给管理员用户一个异常(exception),你可以将你的 Controller 更改为

// check for edit access
if (false === $securityContext->isGranted('EDIT',$comment) && false === $securityContext->isGranted('ROLE_ADMIN') ) {
   throw new AccessDeniedException();
}

关于php - Symfony 2 ACL 和角色层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23406203/

有关php - Symfony 2 ACL 和角色层次结构的更多相关文章

  1. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  2. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  3. ruby-on-rails - (Ruby,Rails) 基于角色的身份验证和用户管理...? - 2

    我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源

  4. ruby-on-rails - 这个 C 和 PHP 程序员如何学习 Ruby 和 Rails? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它

  5. ruby-on-rails - Rails Devise - 管理员角色、模型与属性 - 2

    我知道如何创建管理员角色/用户:https://github.com/plataformatec/devise/wiki/How-To:-Add-an-Admin-role但我想知道的是,在这两个选项之间做出决定时是否需要考虑任何优点或缺点。任何人都可以对此提供任何见解吗? 最佳答案 让我把水弄混一点。我更喜欢通过Role表和连接表UserRole来实现这一点。这样我就可以定义多个角色而无需向数据库添加另一列/表。classUserhas_many:user_roleshas_many:roles,:through=>:user_r

  6. ruby-on-rails - 与 Authlogic 一起使用的一些好的角色授权解决方案是什么? - 2

    我正在寻找一个很好的基于角色的授权解决方案来与Authlogic一起使用。有人有什么好的建议吗?如果可能,请根据您的经验列出一些优缺点。 最佳答案 Acl9与AuthLogic配合得很好:http://github.com/be9/acl9/tree/master 关于ruby-on-rails-与Authlogic一起使用的一些好的角色授权解决方案是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.c

  7. ruby-on-rails - Rails 还是 Sinatra? PHP程序员入门学习哪个好? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。我使用PHP的时间太长了,对它感到厌倦了。我也想学习一门新语言。我一直在使用Ruby并且喜欢它。我必须在Rails和Sinatra之间做出选择,那么您会推荐哪一个?Sinatra真的不能用来构建复杂的应用程序,它只能用于简单的应用程序吗?

  8. ruby - 通过 node-sass 的 Symfony assetic sass 过滤器? - 2

    我在让asseticsass过滤器与node-sass而不是ruby​​替代品一起工作时遇到了一些困难。我的config.yml文件中有以下配置:assetic:debug:"%kernel.debug%"use_controller:falsebundles:[]write-to:"%kernel.root_dir%/../web/assets"read_from:"%kernel.root_dir%/../web/assets"node:"%%PROGRAMFILES%%\nodejs\\node.exe"node_paths:["%%USERPROFILE%%\\AppData\

  9. ruby-on-rails - PHP 魔术方法 __call、__get 和 __set 的 Ruby 等价物 - 2

    我很确定Ruby有这些(等同于__call、__get和__set),否则find_by将如何在Rails中工作?也许有人可以举一个简单的例子来说明如何定义与find_by相同的方法?谢谢 最佳答案 简而言之你可以映射__调用带有参数的method_missing调用__设置为方法名称以'='结尾的method_missing调用__获取不带任何参数的method_missing调用__调用PHPclassMethodTest{publicfunction__call($name,$arguments){echo"Callingob

  10. ruby - Lisp - 是否适合网络编程/应用程序(交互式)? ruby 的方式是? php的方式是? - 2

    Lisp是否适合Web编程/应用程序(交互式),就像ruby​​和php一样?需要考虑的事情是:易于使用可部署性难度(尤其是对于编程初学者而言)(编辑)在阅读PaulGraham'sessay之后,我特别提到了CommonLisp.将是我的第一门编程语言。在这方面。这样做合适吗?我听说Clojure的宏功能不如CommonLisp的强大,这就是我尝试学习Clojure的原因。它教授编程并且非常强大。 最佳答案 Lisp是一个语系,而不是单一的语言。为了稍微回答您的问题,是的,存在用于各种Lisp方言的Web框架,例如用于Common

随机推荐