【发布时间】:2012-02-18 18:17:51
【问题描述】:
所以,我正在尝试在 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 }
那么,access_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>
然后我在 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)
{
// ...
}
}
在每个安全操作中,我都会检查安全用户的凭据(经过身份验证的用户名是否与请求的用户名相同等)。
【问题讨论】: