2014-09-10 83 views
1

我試圖測試由Symfony2完成的CRSF保護系統,非常感謝他們。
我security.yml模板(我修改了默認的。)Symfony2 CRSF保護如何工作?

security: 

    firewalls: 
     dev: 
      pattern: ^/(_(profiler|wdt)|css|images|js)/ 
      security: false 

     login: 
      pattern: ^/demo/secured/login$ 
      security: false 
     secured_area: 
      pattern: ^/demo/secured/ 
      form_login: 
       check_path: _security_check 
       login_path: _demo_login 
       csrf_provider: form.csrf_provider 
      logout: 
       path: _demo_logout 
       target: _demo 
      #anonymous: ~ 
      #http_basic: 
      # realm: "Secured Demo Area" 

    access_control: 
     #- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https } 

在我的形式:

<input type="hidden" name="_csrf_token" value="{{ csrf_token("authenticate") }}"> 

這產生這樣的:

<input type="hidden" name="_csrf_token" value="cKzXBHRDX_sHuT4qt9TAJIwgRvtRMtPnFDtitrSZDuw"> 

我不不知道symfony是如何處理token的驗證的,但在提交我的登錄信息之前,我使用螢火蟲手動更改了令牌的值,如下所示:

<input type="hidden" name="_csrf_token" value="MODIFIEDcKzXBHRDX_sHuT4qt9TAJIwgRvtRMtPnFDtitrSZDuw"> 

當我提交我的登錄名時,我登錄了,這意味着令牌沒有任何影響。 我在哪裏錯了?


獵鷸

  1. Symfony的版本是2.5.2
  2. 該系統時,我手動設置會話變量 「記錄」 爲true簽署了我。從數據庫中讀取並比較密碼後,會發生這種情況。
  3. 表格Html!

    <form id="Loginform" onsubmit="OrganicLogin();return false;"> 
        <input type="hidden" name="_csrf_token" value="{{ csrf_token("authenticate") }}"> 
        <div id="Loginresponse" style="display:none;"></div> 
         <div class="form-group" style="overflow:hidden;"> 
         <label style="margin-top:10px;" for="inputUsername" class="col-lg-2 control-label">Username</label> 
         <div class="col-lg-10"> 
         <input type="text" class="form-control" id="inputUsername" placeholder="Username" style="width:215px;float:right;"> 
         </div> 
         </div> 
         <div class="form-group" style="overflow:hidden;" > 
         <label style="margin-top:10px;" for="inputPassword" class="col-lg-2 control-label">Password</label> 
         <div class="col-lg-10"> 
         <input type="password" class="form-control" id="inputPassword" placeholder="Password" style="width:215px;float:right;"> 
         </div> 
         </div> 
         <div class="form-group" style="overflow:hidden;text-align:center;" > 
         <button type="submit" class="btn btn-primary btn-block" id="submitButton">Access</button> 
         </div></form> 
    
  4. 是的!我做了

  5. 實際上,我一直在爭論整個時間,我以本地方式進行登錄過程,形式,用JS讀取數據,向控制器發送POST請求,控制器檢查輸入並設置會話。

  6. 沒有,全部由手工完成

  7. 其實這是我第一次使用security.yml,我只是去掉了一些部分我不判斷此線程

  8. 沒有有用的..

+0

我的登錄網址是/ login – Sekai 2014-09-10 13:57:01

+0

您可以通過cURL和POST方法測試ist(只是不要設置_csrf_token字段)並打印輸出。 – 2014-09-10 14:39:06

+0

我是否需要在控制器中寫入任何內容? – Sekai 2014-09-10 15:36:50

回答

2

我有點猜測你的更改令牌沒有發佈。在堅持模具:

namespace Symfony\Component\Form\Extension\Csrf\CsrfProvider; 

class DefaultCsrfProvider implements CsrfProviderInterface 
{ 
    public function isCsrfTokenValid($intention, $token) 
    { 
     die('csrf token ' . $intention . ' ' . $token); 
     return $token === $this->generateCsrfToken($intention); 
    } 

如果達到模具那麼你知道你的配置是可以的,當然你可以看到實際的發佈令牌。

不用說,你也應該clearcache。

============================================== =========

更新1 - 經過多次評論後,我們確定die()沒有被調用。進展。

不幸的是我們仍然需要驗證海報如何配置他們的系統。

下一步 - 無需通過螢火蟲調整csrf標記並驗證是否已達到die語句即可登錄。

舉報這種或那種方式。

不用說(但我可以說是反正),請確保您嘗試重新登錄之前註銷。

=================== =====================================

Update 2 - die語句不存在即使使用正常登錄也能達到。

所以現在來我最喜歡的部分。鷸狩獵。基本上,我在閱讀這個問題時做了一些假設。需要通過提出一些基本問題來確定哪些假設是不正確的。

  1. 您正在使用哪個版本的Symfony 2。我假設至少S2.1。

  2. 你怎麼知道系統已經簽了你?您是否使用調試工具欄,它是否顯示您正在進行身份驗證?當您嘗試使用不正確的密碼登錄時會發生什麼?

  3. 使用瀏覽器的查看源代碼功能並將生成的表單複製到您的問題中。特別是我想看到動作屬性,但我也想看到輸入元素。

  4. 事實上,你是否已經將die聲明添加到vendor/symfony/symfony/src/Symfony/Component/Form/Csrf/CsrfProvider/DefaultCsrfProvider.php?編輯完後是否保存了文件?

  5. 你實際上是在使用標準的form_login進程嗎?你沒有任何代碼,例如,檢查用戶密碼?

  6. 您是否在使用其他任何軟件包,比如FOSUserBundle?

  7. 問題中的security.yml文件真的是你的實際文件?複製後你沒有「清理乾淨」?

  8. 你有沒有檢查你的應用程序到github?如果是這樣,你可以提供一個鏈接?看看整個應用程序可能是解決這個問題的最快方法。

現在應該足夠了。用你的答案更新你的問題。

============================================== ===========================

更新3 - 情節變得

正如我在上面的問題我們打字發現基本登錄系統本身沒有正確配置。調試工具欄指示用戶未通過身份驗證。更多進展!經常發生,症狀掩蓋了實際問題。

安全系統可以說是Symfony 2中最複雜的組件,典型的開發者需要與之交互。配置時很容易混淆,難以排除故障。一個小小的錯字可以把事情弄糟。對開發人員來說,瞭解安全性如何實施也是非常重要的。除非你是像Target或Home Depot那樣的大公司。

我的建議是使用作曲家創建一個新的Symfony 2項目。然後逐步完成http://symfony.com/doc/current/book/security.html並配置安全系統。讓它成爲理解安全性的參考應用。

在這個過程結束時,我懷疑你已經找出了問題並且可以將解決方案應用到你現有的應用程序中。作爲獎勵,你將有一些你可以參考的未來問題。

============================================== ====================

更新4日 - 激動人心的結論

所以現在我們發現,正在使用的自定義和天真的登錄系統。

我仍然建議重新開始一個新項目,並讓Symfony 2的方式工作。之後,如果您真的想要,可以調整登錄表單以使用JavaScript。

如果你真的真的真的想用自己的系統,然後從這裏開始:Manual authenticate user

但是你會折騰出的Symfony的主要優勢之一併沒有任何特別的理由。

+0

這實際上是我的原始問題,我是否需要在控制器中添加某些內容以使保護工作正常? – Sekai 2014-09-10 15:34:29

+0

不是。它看起來像你遵循這個:http://symfony.com/doc/current/cookbook/security/csrf_in_login_form.html。這就是你需要做的。控制器在檢查登錄過程中永遠不會被擊中。所有與聽衆完成。如果die聲明已經達到,那麼你已經正確配置了它。如果沒有,那麼你有其他事情正在進行。 – Cerad 2014-09-10 15:44:11

+0

如果您真的想要用戶身份驗證的醜陋細節,請查看:http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html。但這不是因爲內心的淡淡。當我最終說,isCsrfTokenValid()被調用時,請相信我。 – Cerad 2014-09-10 15:47:54

1

它應該工作的方式是Symfony生成一個CSRF令牌,它會自動插入到表單中。它將此令牌存儲在當前會話中。提交表單時,它會將提交的標記與會話中存儲的值進行比較。關於你的具體情況,這聽起來像是CSRF沒有實際啓用,它可能與安全上下文不被安全區域防火牆共享,安全區域防火牆已啓用CSRF,登錄防火牆不支持。

嘗試刪除您的security.yml該位:

login: 
    pattern: ^/demo/secured/login$ 
    security: false 

,而是,它移動到secured_area上下文和使用訪問控制,授權訪問:

... 

form_login: 
    check_path: _security_check 
    login_path: login 
... 

access_control: 
    - { path: ^/demo/secured/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https } 

或者,你可以嘗試爲您的登錄防火牆添加context: secured_area。根據我的經驗,如果登錄防火牆與安全區域不在同一個上下文中,則無法完全從登錄控制器訪問安全上下文。