Security Symfony2-URL的安全特定HTTP方法

Security Symfony2-URL的安全特定HTTP方法,security,api,rest,symfony,Security,Api,Rest,Symfony,所以,我试图在Symfony2中创建一个RESTful API,但我遇到了一个安全问题 比方说,我想用我的API创建一个新用户。我将按照以下要求行事: POST/api/v1/users.json HTTP/1.1 所有客户端都可以访问此URL,因此不需要身份验证。但是,假设我想请求所有用户的列表。根据剩下的想法,我应该提出一个GET请求: GET/api/v1/users.json HTTP/1.1 当然,我不希望每个人都能访问此列表,因此我必须将其保存在Symfony2中。当然,以下操作不起

所以,我试图在Symfony2中创建一个RESTful API,但我遇到了一个安全问题

比方说,我想用我的API创建一个新用户。我将按照以下要求行事:

POST/api/v1/users.json HTTP/1.1

所有客户端都可以访问此URL,因此不需要身份验证。但是,假设我想请求所有用户的列表。根据剩下的想法,我应该提出一个GET请求:

GET/api/v1/users.json HTTP/1.1

当然,我不希望每个人都能访问此列表,因此我必须将其保存在Symfony2中。当然,以下操作不起作用,因为它保护了整个URL模式,而不是HTTP方法:

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:
        in_memory:
            users:
                user:  { password: userpass, roles: [ 'ROLE_USER' ] }
                admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }

    firewalls:
        secured_area:
            pattern:    ^/
            anonymous: ~
            http_basic:
                realm: "Social Portal API"

    access_control:
        - { path: /api/v1/users.json, roles: ROLE_ADMIN }
那么,
access\u control
指令是否有一个秘密参数来保护HTTP方法?或者还有别的办法吗?我已尝试使用JMSSecurityExtraBundle:

/**
 * @Secure(roles="ROLE_ADMIN")
 */
public function listAction()
{
    return new Response('Cubilon\\SocialPortal\\APIBundle\\Controller\\UserController', 200);
}
它应该保护此方法,但它不起作用

如何结合URL模式保护某个HTTP方法

编辑:

因此,正如我在下面的答案中所说,我已经使用JMSSecurityExtraBundle修复了它。我已在Resources/config/services.xml中定义了要保护的服务:

# Resources/config/services.xml
<?xml version="1.0" encoding="utf-8"?>
<services>
    <service id="user_controller" class="Cubilon\SocialPortal\APIBundle\Controller\UserController">
        <tag name="security.secure_service" />
    </service>
</services>
#Resources/config/services.xml
然后我在UserController中相应地保护了每个操作:

# Controller/UserController.php
<?php
namespace Cubilon\SocialPortal\APIBundle\Controller\UserController;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use JMS\SecurityExtraBundle\Annotation\Secure;

class UserController extends Controller
{
    public function createAction($_format)
    {
        // ...
    }

    /**
     * @Secure(roles="ROLE_USER, ROLE_ADMIN")
     */
    public function readAction($username, $_format)
    {
        // ...
    }

    /**
     * @Secure(roles="ROLE_USER, ROLE_ADMIN")
     */
    public function updateAction($username, $_format)
    {
        // ...
    }

    /**
     * @Secure(roles="ROLE_USER, ROLE_ADMIN")
     */
    public function deleteAction($username, $_format)
    {
        // ...
    }
}
#Controller/UserController.php
根据,您无法通过方法保护URL

不是最好的方式,但你可以这样做,在行动中:

public function listAction(Request $request)
{
    if ($request->getMethod() == 'GET' && !$this->get('security.context')->isGranted('ROLE_ADMINISTRATOR')) {
        throw $this->createNotFoundException("This page doesn't exist."); // forward a 404, or a message in a json...
    }

    return new Response('Cubilon\\SocialPortal\\APIBundle\\Controller\\UserController', 200);
}

或者您可以创建一个新的,将检查方法和用户角色,就像我前面的示例一样,但扩展到所有操作^^

我知道现在已经晚了,但是如果有人无意中发现了这个问题,这里的问题是如何确保每个HTTP方法的每个请求的安全(请参阅):


注意设置规则的顺序很重要。

注意,有两件事:

  • 防火墙(身份验证)
  • 访问控制(授权)
接受的答案显示了如何将访问控制规则限制为HTTP方法,但下面是如何将防火墙规则限制为HTTP方法:

security:
    firewalls:
        secured_area:
            methods: [POST, PUT]
security:
    # ...
    access_control:
        - { path: ^/api/v1/users.json, roles: ROLE_ADMIN, methods: [POST, PUT] }
请注意,此功能是在Symfony 2.5中添加的

如另一个答案所示,下面是如何将访问控制规则限制为HTTP方法的

security:
    firewalls:
        secured_area:
            methods: [POST, PUT]
security:
    # ...
    access_control:
        - { path: ^/api/v1/users.json, roles: ROLE_ADMIN, methods: [POST, PUT] }

我最终用JMSSecurityExtraBundle修复了它,就像我以前尝试的那样,但我不知怎么的没有读到你也必须指定类。雷蒙:你能详细谈谈你的评论吗?如何指定类?我认为这是正确的答案。防火墙仅处理post、put(删除)方法,并应用相应的防护