2011-11-30 35 views
6

我想強制用戶使用HTTPS而不是HTTP,但只能在認證後使用。我發現的唯一選擇是在每個控制器/方法的基礎上強制HTTPS。匿名用戶應該只使用HTTP。Symfony2,認證後切換到HTTPS

如何僅通過驗證的用戶設置強制HTTPS和強制不限於在我的包的所有控制器使用HTTPS未經驗證的用戶?

再次 - 這是不是禁用HTTPS授權頁面。

我想用所有的驗證和未經驗證的用戶相同的控制器,但強迫那些登錄到使用HTTPS,和那些誰不使用HTTP。用戶通過身份驗證時,基本上會爲所有控制器添加HTTPS要求。

這個問題的Symfony 2特異性。我想用Symfony機制來做。我知道如何檢測這個東西,但它會破壞Twig鏈接。 Symfony可以自動切換到HTTPS,我只想知道如何在每個用戶角色的基礎上做到這一點,而不是基於每個控制器。

+0

你有問題嗎? – JJJ

+1

未使用HTTPS進行身份驗證是一個不好的決定。這意味着發送/接收的數據是純文本,任何訪問客戶端和服務器之間路由中任何計算機的人都能夠讀取數據包並收集憑據(用戶,密碼,cookie等)。有沒有不使用SSL進行身份驗證的特殊原因? – jweyrich

+2

@jweyrich這不是問題。我希望用戶在授權之後(這是外部btw)對所有後續頁面使用https,併爲未經授權的用戶禁用https。 –

回答

10

人們會認爲存取控制器會爲我們做這一點:

access_control: 
    - { role: ROLE_USER, requires_channel: https } 
    - { role: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: http } 

但,不......我認爲這將是一個非常不錯的功能,但。

在這種情況下,我們可以請求收聽使用內核事件一起砍東西:

namespace YourBundle\EventListener; 

use Symfony\Component\HttpKernel\Event\GetResponseEvent; 
use Symfony\Component\HttpFoundation\RedirectResponse; 

class RequestListener 
{ 
    public function onKernelRequest(GetResponseEvent $event) 
    { 
     $request = $event->getRequest(); 

     // force ssl based on authentication 
     if ($this->container->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY')) { 
      if (!$request->isSecure()) { 
       $request->server->set('HTTPS', true); 
       $request->server->set('SERVER_PORT', 443); 
       $event->setResponse(new RedirectResponse($request->getUri())); 
      } 
     } else { 
      if ($request->isSecure()) { 
       $request->server->set('HTTPS', false); 
       $request->server->set('SERVER_PORT', 80); 
       $event->setResponse(new RedirectResponse($request->getUri())); 
      } 
     } 
    } 
} 

定義你的聽衆在config.yml下服務:

myapp.request.listener: 
    class: MyApp\MyBundle\EventListener\RequestListener 
    tags: 
     - { name: kernel.event_listener, event: kernel.request } 

Symfony Internals的細節事件等。

+1

您可以檢查我們的捆綁軟件,它允許自動化行爲,例如爲登錄用戶強制ssl,如果他們不通過https訪問該網站,則不給予403:https://github.com/nelmio/NelmioSecurityBundle – Seldaek

2

在Symfony的2.0.11,我得到一個重定向錯誤。 爲了解決這個問題,我在監聽器中註釋了以下幾行。

class RequestListener { 
    public function onKernelRequest(GetResponseEvent $event) { 
     $request = $event->getRequest(); 

     // force ssl based on authentication 
     if  ($this->container->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY')) { 
      if (!$request->isSecure()) { 
       $request->server->set('HTTPS', true); 
       $request->server->set('SERVER_PORT', 443); 
       // $event->setResponse(new RedirectResponse($request->getUri())); 
      } 
     } else { 
      if ($request->isSecure()) { 
       $request->server->set('HTTPS', false); 
       $request->server->set('SERVER_PORT', 80); 
       // $event->setResponse(new RedirectResponse($request->getUri())); 
      } 
     } 
    } 
}