2012-01-25 8 views
10

私はSymfony2でRESTful APIを作成しようとしていますが、セキュリティに問題があります。symfony2 - URLのセキュリティで保護されたHTTPメソッド

たとえば、APIを使用して新しいユーザーを作成したいとします。

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

必要な認証がありませんので、このURLは、すべてのクライアントによりづけしなければなりません:私は、次のリクエストを行います。しかし、すべてのユーザーのリストを要求したいとしましょう。 RESTの考え方によると、私はGETリクエストにする必要があります。もちろん

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

を、私はこのリストは誰でもづけしにしたくないので、私はSymfony2の中でそれを確保する必要があります。だから、

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ディレクティブの秘密のパラメータがあります:それはHTTPメソッドを全体のURLパターンを確保し、ではないので、以下では、当然のことながら、動作しないのだろうか?それとも他の方法がありますか?

がどのように私はURLパターンと組み合わせて、特定のHTTPメソッドを確保することができます...

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

この方法を確保しなければならないが、それはうまくいきませんでした:私はJMSSecurityExtraBundleを使用しようとしましたか?

編集:私は以下の答えの下で述べたように

、私はJMSSecurityExtraBundleを使用して、それを修正しました。私は/設定/ 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) 
    { 
     // ... 
    } 
} 

(認証されたユーザー名が要求されたユーザー名などと同じかどうか)を確認します。

答えて

12

ルールの問題を設定します。

4

security reference bookによれば、方法で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); 
} 

それとも、私の前の例のような方法とユーザーの役割を確認し、それに拡張する新しいkernel event listenerを作成することができますがすべてのアクション!

# 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 } 

はであなたの順序に注意してください:私はそれが遅れている知っている、誰かがここにこの質問につまずく場合(Symfony security documentationを参照してください)HTTPメソッドごとの要求ごとに確保する方法です^^

+0

が、私は何とかのdidnあなたがクラスを指定しなければならないことも読んでいない。 –

+2

Ramon:あなたのコメントをお待ちしていますか?どのようにクラスを指定しますか? –

+0

私はどのように修正したかを明確にするために質問を編集しました。 –

2

気をつけて、2つのことがあります。

  • ファイアウォール(認証)
  • アクセス制御(承認)

受け入れ答えは、HTTPへのアクセス制御ルールを制限する方法を示しています方法はここにありますファイアウォールルールをHTTPメソッドに制限する方法

security: 
    firewalls: 
     secured_area: 
      methods: [POST, PUT] 

この機能は、Symfony 2.5に追加されています。

他の回答に示すように、ここでHTTPメソッドへのアクセス制御ルールを制限する方法である:私は前に試したと私は最終的にJMSSecurityExtraBundleを使用して、それを修正した

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