所以,我正在尝试在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 }
那么,是否存在保护HTTP方法的access_control
指令的秘密参数?或者还有其他方法吗?我试过使用JMSSecurityExtraBundle:
/**
* @Secure(roles="ROLE_ADMIN")
*/
public function listAction()
{
return new Response('Cubilon\\SocialPortal\\APIBundle\\Controller\\UserController', 200);
}
哪个应该保护这个方法,但它不起作用......
如何将某种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>
然后我在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)
{
// ...
}
}
在每个安全操作中,我检查安全用户的凭据(经过身份验证的用户名是否与请求的用户名相同等)。
答案 0 :(得分:12)
我知道现在已经很晚了,但如果有人偶然发现这个问题,那么每个HTTP方法的请求是如何保证的(请参阅Symfony security documentation):
# 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 }
请注意设置规则的顺序。
答案 1 :(得分:4)
根据security reference book,您无法通过方法保护网址。
不是最好的方法,但你可以在行动中这样做:
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);
}
或者您可以创建一个新的kernel event listener来检查方法和用户ROLE,就像我之前的示例一样,但扩展到所有操作! ^^
答案 2 :(得分:3)
注意,有两件事:
接受的答案显示了如何将访问控制规则限制为HTTP方法,但以下是如何将防火墙规则限制为HTTP方法:
security:
firewalls:
secured_area:
methods: [POST, PUT]
请注意,此功能已添加到 Symfony 2.5 。
中如另一个答案所示,以下是如何将访问控制规则限制为HTTP方法:
security:
# ...
access_control:
- { path: ^/api/v1/users.json, roles: ROLE_ADMIN, methods: [POST, PUT] }