Symfony2 - 为URL保护特定的HTTP方法

Ram*_*iss 10 security api rest symfony

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

比方说,我想用API创建一个新用户.我会做以下要求:

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

所有客户端都应该可以访问此URL,因此无需进行身份验证.但是,假设我想要请求所有用户的列表.根据REST的想法,我应该提出一个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 }
Run Code Online (Sandbox Code Playgroud)

那么,是否有一个access_control保护HTTP方法的指令的秘密参数?或者还有其他方法吗?我试过使用JMSSecurityExtraBundle:

/**
 * @Secure(roles="ROLE_ADMIN")
 */
public function listAction()
{
    return new Response('Cubilon\\SocialPortal\\APIBundle\\Controller\\UserController', 200);
}
Run Code Online (Sandbox Code Playgroud)

哪个应该保护这个方法,但它不起作用......

如何将某种HTTP方法与URL模式结合使用?

编辑:

所以,正如我在下面的答案中所说,我已经使用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>
Run Code Online (Sandbox Code Playgroud)

然后我在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)
    {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

在每个安全操作中,我检查安全用户的凭据(经过身份验证的用户名是否与请求的用户名相同等).

小智 12

我知道它已经很晚了,但是如果有人在这个问题上遇到问题,那么如何根据每个HTTP方法的请求进行保护(请参阅Symfony安全文档):

# app/config/security.yml
security:
    # ...
    access_control:
        - { path: ^/api/v1/users.json, roles: ROLE_ADMIN, methods: [POST, PUT] }
        - { path: /api/v1/users.json, roles: ROLE_ADMIN }
Run Code Online (Sandbox Code Playgroud)

请注意设置规则的顺序.


Mat*_*oli 5

请注意,有两件事:

  • 防火墙(身份验证)
  • 访问控制(授权)

接受的答案显示了如何将访问控制规则限制为 HTTP 方法,但以下是如何将防火墙规则限制为 HTTP 方法

security:
    firewalls:
        secured_area:
            methods: [POST, PUT]
Run Code Online (Sandbox Code Playgroud)

请注意,此功能是在Symfony 2.5中添加的。

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

security:
    # ...
    access_control:
        - { path: ^/api/v1/users.json, roles: ROLE_ADMIN, methods: [POST, PUT] }
Run Code Online (Sandbox Code Playgroud)